[Rt-commit] r18559 - rt/3.8/trunk/lib/RT
ruz at bestpractical.com
ruz at bestpractical.com
Tue Feb 24 06:48:19 EST 2009
Author: ruz
Date: Tue Feb 24 06:48:15 2009
New Revision: 18559
Modified:
rt/3.8/trunk/lib/RT/Tickets_Overlay.pm
Log:
* fix searches by CFs
Modified: rt/3.8/trunk/lib/RT/Tickets_Overlay.pm
==============================================================================
--- rt/3.8/trunk/lib/RT/Tickets_Overlay.pm (original)
+++ rt/3.8/trunk/lib/RT/Tickets_Overlay.pm Tue Feb 24 06:48:15 2009
@@ -1345,16 +1345,12 @@
($queue, $field, $cf, $column) = $self->_CustomFieldDecipher( $field );
$cfid = $cf ? $cf->id : 0 ;
-
# 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. Note that
# we explicitly don't include the "IS NULL" case, since we would
# otherwise end up with a redundant clause.
- my $null_columns_ok;
- if ( ( $op =~ /^NOT LIKE$/i ) or ( $op eq '!=' ) ) {
- $null_columns_ok = 1;
- }
+ my ($negative_op, $null_op, $inv_op) = $self->ClassifySQLOperation( $op );
my $fix_op = sub {
my $op = shift;
@@ -1364,96 +1360,160 @@
return $op;
};
- my $cfkey = $cfid ? $cfid : "$queue.$field";
- my ($TicketCFs, $CFs) = $self->_CustomFieldJoin( $cfkey, $cfid, $field );
-
- $self->_OpenParen;
+ my $single_value = !$cf || !$cfid || $cf->SingleValue;
- $self->_OpenParen;
+ my $cfkey = $cfid ? $cfid : "$queue.$field";
- $self->_OpenParen;
- # if column is defined then deal only with it
- # otherwise search in Content and in LargeContent
- if ( $column ) {
+ if ( $null_op && !$column ) {
+ # IS[ NOT] NULL without column is the same as has[ no] any CF value,
+ # we can reuse our default joins for this operation
+ # with column specified we have different situation
+ my ($TicketCFs, $CFs) = $self->_CustomFieldJoin( $cfkey, $cfid, $field );
+ $self->_OpenParen;
$self->_SQLLimit(
- ALIAS => $TicketCFs,
- FIELD => $column,
- OPERATOR => ($column ne 'LargeContent'? $op : $fix_op->($op)),
- VALUE => $value,
+ ALIAS => $TicketCFs,
+ FIELD => 'id',
+ OPERATOR => $op,
+ VALUE => $value,
%rest
);
- }
- else {
$self->_SQLLimit(
- ALIAS => $TicketCFs,
- FIELD => 'Content',
- OPERATOR => $op,
- VALUE => $value,
- %rest
- );
+ ALIAS => $CFs,
+ FIELD => 'Name',
+ OPERATOR => 'IS NOT',
+ VALUE => 'NULL',
+ QUOTEVALUE => 0,
+ ENTRYAGGREGATOR => 'AND',
+ ) if $CFs;
+ $self->_CloseParen;
+ }
+ elsif ( !$negative_op || $single_value ) {
+ $cfkey .= '.'. $self->{'_sql_multiple_cfs_index'}++ unless $single_value;
+ my ($TicketCFs, $CFs) = $self->_CustomFieldJoin( $cfkey, $cfid, $field );
$self->_OpenParen;
+
$self->_OpenParen;
- $self->_SQLLimit(
- ALIAS => $TicketCFs,
- FIELD => 'Content',
- OPERATOR => '=',
- VALUE => '',
- ENTRYAGGREGATOR => 'OR'
- );
- $self->_SQLLimit(
- ALIAS => $TicketCFs,
- FIELD => 'Content',
- OPERATOR => 'IS',
- VALUE => 'NULL',
- ENTRYAGGREGATOR => 'OR'
- );
+
+ $self->_OpenParen;
+ # if column is defined then deal only with it
+ # otherwise search in Content and in LargeContent
+ if ( $column ) {
+ $self->_SQLLimit(
+ ALIAS => $TicketCFs,
+ FIELD => $column,
+ OPERATOR => ($column ne 'LargeContent'? $op : $fix_op->($op)),
+ VALUE => $value,
+ %rest
+ );
+ }
+ else {
+ $self->_SQLLimit(
+ ALIAS => $TicketCFs,
+ FIELD => 'Content',
+ OPERATOR => $op,
+ VALUE => $value,
+ %rest
+ );
+
+ $self->_OpenParen;
+ $self->_OpenParen;
+ $self->_SQLLimit(
+ ALIAS => $TicketCFs,
+ FIELD => 'Content',
+ OPERATOR => '=',
+ VALUE => '',
+ ENTRYAGGREGATOR => 'OR'
+ );
+ $self->_SQLLimit(
+ ALIAS => $TicketCFs,
+ FIELD => 'Content',
+ OPERATOR => 'IS',
+ VALUE => 'NULL',
+ ENTRYAGGREGATOR => 'OR'
+ );
+ $self->_CloseParen;
+ $self->_SQLLimit(
+ ALIAS => $TicketCFs,
+ FIELD => 'LargeContent',
+ OPERATOR => $fix_op->($op),
+ VALUE => $value,
+ ENTRYAGGREGATOR => 'AND',
+ );
+ $self->_CloseParen;
+ }
$self->_CloseParen;
+
+ # XXX: if we join via CustomFields table then
+ # because of order of left joins we get NULLs in
+ # CF table and then get nulls for those records
+ # in OCFVs table what result in wrong results
+ # as decifer method now tries to load a CF then
+ # we fall into this situation only when there
+ # are more than one CF with the name in the DB.
+ # the same thing applies to order by call.
+ # TODO: reorder joins T <- OCFVs <- CFs <- OCFs if
+ # we want treat IS NULL as (not applies or has
+ # no value)
$self->_SQLLimit(
- ALIAS => $TicketCFs,
- FIELD => 'LargeContent',
- OPERATOR => $fix_op->($op),
- VALUE => $value,
+ ALIAS => $CFs,
+ FIELD => 'Name',
+ OPERATOR => 'IS NOT',
+ VALUE => 'NULL',
+ QUOTEVALUE => 0,
ENTRYAGGREGATOR => 'AND',
- );
+ ) if $CFs;
+ $self->_CloseParen;
+
+ if ($negative_op) {
+ $self->_SQLLimit(
+ ALIAS => $TicketCFs,
+ FIELD => $column || 'Content',
+ OPERATOR => 'IS',
+ VALUE => 'NULL',
+ QUOTEVALUE => 0,
+ ENTRYAGGREGATOR => 'OR',
+ );
+ }
+
$self->_CloseParen;
}
- $self->_CloseParen;
+ else {
+ $cfkey .= '.'. $self->{'_sql_multiple_cfs_index'}++;
+ my ($TicketCFs, $CFs) = $self->_CustomFieldJoin( $cfkey, $cfid, $field );
- # XXX: if we join via CustomFields table then
- # because of order of left joins we get NULLs in
- # CF table and then get nulls for those records
- # in OCFVs table what result in wrong results
- # as decifer method now tries to load a CF then
- # we fall into this situation only when there
- # are more than one CF with the name in the DB.
- # the same thing applies to order by call.
- # TODO: reorder joins T <- OCFVs <- CFs <- OCFs if
- # we want treat IS NULL as (not applies or has
- # no value)
- $self->_SQLLimit(
- ALIAS => $CFs,
- FIELD => 'Name',
- OPERATOR => 'IS NOT',
- VALUE => 'NULL',
- QUOTEVALUE => 0,
- ENTRYAGGREGATOR => 'AND',
- ) if $CFs;
- $self->_CloseParen;
+ # reverse operation
+ $op =~ s/!|NOT\s+//i;
- if ($null_columns_ok) {
+ # if column is defined then deal only with it
+ # otherwise search in Content and in LargeContent
+ if ( $column ) {
+ $self->SUPER::Limit(
+ LEFTJOIN => $TicketCFs,
+ ALIAS => $TicketCFs,
+ FIELD => $column,
+ OPERATOR => ($column ne 'LargeContent'? $op : $fix_op->($op)),
+ VALUE => $value,
+ );
+ }
+ else {
+ $self->SUPER::Limit(
+ LEFTJOIN => $TicketCFs,
+ ALIAS => $TicketCFs,
+ FIELD => 'Content',
+ OPERATOR => $op,
+ VALUE => $value,
+ );
+ }
$self->_SQLLimit(
- ALIAS => $TicketCFs,
- FIELD => $column || 'Content',
- OPERATOR => 'IS',
- VALUE => 'NULL',
- QUOTEVALUE => 0,
- ENTRYAGGREGATOR => 'OR',
+ %rest,
+ ALIAS => $TicketCFs,
+ FIELD => 'id',
+ OPERATOR => 'IS',
+ VALUE => 'NULL',
+ QUOTEVALUE => 0,
);
}
-
- $self->_CloseParen;
-
}
# End Helper Functions
More information about the Rt-commit
mailing list