[Rt-commit] rt branch, 4.2/tickets-cleanup, created. rt-4.1.5-282-gc64e974

Alex Vandiver alexmv at bestpractical.com
Fri Jan 11 19:01:25 EST 2013


The branch, 4.2/tickets-cleanup has been created
        at  c64e974f6c1f8eea3c17c4621935b22a3f4ae0e3 (commit)

- Log -----------------------------------------------------------------
commit 43710e2a531de08952d70162c9373c53c242dae2
Author: Alex Vandiver <alexmv at bestpractical.com>
Date:   Fri Jan 11 06:19:12 2013 -0500

    Remove ClassifySQLOperation

diff --git a/lib/RT/Tickets.pm b/lib/RT/Tickets.pm
index abc27ca..cc13e14 100644
--- a/lib/RT/Tickets.pm
+++ b/lib/RT/Tickets.pm
@@ -1214,8 +1214,8 @@ sub _CustomFieldLimit {
 # we explicitly don't include the "IS NULL" case, since we would
 # otherwise end up with a redundant clause.
 
-    my ($negative_op, $null_op, $inv_op, $range_op)
-        = $self->ClassifySQLOperation( $op );
+    my $negative_op = ($op eq '!=' || $op =~ /\bNOT\b/i);
+    my $null_op = ( 'is not' eq lc($op) || 'is' eq lc($op) );
 
     my $fix_op = sub {
         return @_ unless RT->Config->Get('DatabaseType') eq 'Oracle';
@@ -1347,7 +1347,7 @@ sub _CustomFieldLimit {
         $self->_CloseParen;
     } 
     elsif ( !$negative_op || $single_value ) {
-        $cfkey .= '.'. $self->{'_sql_multiple_cfs_index'}++ if !$single_value && !$range_op;
+        $cfkey .= '.'. $self->{'_sql_multiple_cfs_index'}++ if not $single_value and not $op =~ /^[<>]=?$/;
         my ($TicketCFs, $CFs) = $self->_CustomFieldJoin( $cfkey, $cfid, $field );
 
         $self->_OpenParen;
diff --git a/lib/RT/Tickets_SQL.pm b/lib/RT/Tickets_SQL.pm
index 08c1ed8..fab1235 100644
--- a/lib/RT/Tickets_SQL.pm
+++ b/lib/RT/Tickets_SQL.pm
@@ -284,36 +284,6 @@ sub Query {
     return ($_[0]->{_sql_query});
 }
 
-{
-my %inv = (
-    '=' => '!=', '!=' => '=', '<>' => '=',
-    '>' => '<=', '<' => '>=', '>=' => '<', '<=' => '>',
-    'is' => 'IS NOT', 'is not' => 'IS',
-    'like' => 'NOT LIKE', 'not like' => 'LIKE',
-    'matches' => 'NOT MATCHES', 'not matches' => 'MATCHES',
-    'startswith' => 'NOT STARTSWITH', 'not startswith' => 'STARTSWITH',
-    'endswith' => 'NOT ENDSWITH', 'not endswith' => 'ENDSWITH',
-);
-
-my %range = map { $_ => 1 } qw(> >= < <=);
-
-sub ClassifySQLOperation {
-    my $self = shift;
-    my $op = shift;
-
-    my $is_negative = 0;
-    if ( $op eq '!=' || $op =~ /\bNOT\b/i ) {
-        $is_negative = 1;
-    }
-
-    my $is_null = 0;
-    if ( 'is not' eq lc($op) || 'is' eq lc($op) ) {
-        $is_null = 1;
-    }
-
-    return ($is_negative, $is_null, $inv{lc $op}, $range{lc $op});
-} }
-
 1;
 
 =pod

commit 2fed54ab9b7aae1bb2708265ae32633aceda7e52
Author: Alex Vandiver <alexmv at bestpractical.com>
Date:   Fri Jan 11 06:46:44 2013 -0500

    Be consistent about ->{looking_at_foo} vs ->{_sql_looking_at}{foo}
    
    The code was inconsistent, setting both in different places, and
    checking them similarly inconsistently.  Settle on the _sql_looking_at
    form, which is the one which was more relevant internally.

diff --git a/lib/RT/Tickets.pm b/lib/RT/Tickets.pm
index cc13e14..b261c47 100644
--- a/lib/RT/Tickets.pm
+++ b/lib/RT/Tickets.pm
@@ -1763,16 +1763,14 @@ sub Limit {
     delete $self->{'raw_rows'};
     delete $self->{'count_all'};
 
-    $args{ALIAS} ||= 'main';
-    $self->{'looking_at_effective_id'} = 1
-        if $args{'ALIAS'} eq 'main' and $args{'FIELD'} eq 'EffectiveId';
-    $self->{'looking_at_type'} = 1
-        if $args{'ALIAS'} eq 'main' and $args{'FIELD'} eq 'Type';
-
     if ($self->{'using_restrictions'}) {
         RT->Deprecated( Message => "Mixing old-style LimitFoo methods with Limit is deprecated" );
         $self->LimitField(@_);
     }
+
+    $self->{_sql_looking_at}{ lc $args{FIELD} } = 1
+        if (not $args{ALIAS} or $args{ALIAS} eq "main");
+
     $self->SUPER::Limit(@_);
 }
 
@@ -1944,7 +1942,7 @@ sub IgnoreType {
     # Tickets_SQL/FromSQL goes down the right branch
 
     #  $self->LimitType(VALUE => '__any');
-    $self->{looking_at_type} = 1;
+    $self->{_sql_looking_at}{type} = 1;
 }
 
 
@@ -2660,8 +2658,6 @@ sub _Init {
     my $self = shift;
     $self->{'table'}                   = "Tickets";
     $self->{'RecalcTicketLimits'}      = 1;
-    $self->{'looking_at_effective_id'} = 0;
-    $self->{'looking_at_type'}         = 0;
     $self->{'restriction_index'}       = 1;
     $self->{'primary_key'}             = "id";
     delete $self->{'items_array'};
@@ -3086,8 +3082,7 @@ Removes all restrictions irretrievably
 sub ClearRestrictions {
     my $self = shift;
     delete $self->{'TicketRestrictions'};
-    $self->{'looking_at_effective_id'} = 0;
-    $self->{'looking_at_type'}         = 0;
+    $self->{_sql_looking_at} = {};
     $self->{'RecalcTicketLimits'}      = 1;
 }
 
@@ -3330,7 +3325,6 @@ RT::Tickets supports several flags which alter search behavior:
 
 
 allow_deleted_search  (Otherwise never show deleted tickets in search results)
-looking_at_type (otherwise limit to type=ticket)
 
 These flags are set by calling 
 
diff --git a/lib/RT/Tickets_SQL.pm b/lib/RT/Tickets_SQL.pm
index fab1235..67b6e07 100644
--- a/lib/RT/Tickets_SQL.pm
+++ b/lib/RT/Tickets_SQL.pm
@@ -169,7 +169,6 @@ sub _parser {
                 ENTRYAGGREGATOR => $ea,
                 SUBKEY          => $subkey,
               );
-        $self->{_sql_looking_at}{lc $key} = 1;
         $ea = '';
     };
     RT::SQL::Parse($string, \%callback);
@@ -219,10 +218,10 @@ sub FromSQL {
 
     {
         # preserve first_row and show_rows across the CleanSlate
-        local ($self->{'first_row'}, $self->{'show_rows'});
+        local ($self->{'first_row'}, $self->{'show_rows'}, $self->{_sql_looking_at});
         $self->CleanSlate;
+        $self->_InitSQL();
     }
-    $self->_InitSQL();
 
     return (1, $self->loc("No Query")) unless $query;
 
@@ -234,29 +233,16 @@ sub FromSQL {
     }
 
     # We only want to look at EffectiveId's (mostly) for these searches.
-    unless ( exists $self->{_sql_looking_at}{'effectiveid'} ) {
-        #TODO, we shouldn't be hard #coding the tablename to main.
-        $self->SUPER::Limit( FIELD           => 'EffectiveId',
-                             VALUE           => 'main.id',
-                             ENTRYAGGREGATOR => 'AND',
-                             QUOTEVALUE      => 0,
-                           );
+    unless ( $self->{_sql_looking_at}{effectiveid} ) {
+        $self->Limit(
+            FIELD           => 'EffectiveId',
+            VALUE           => 'main.id',
+            ENTRYAGGREGATOR => 'AND',
+            QUOTEVALUE      => 0,
+        );
     }
-    # FIXME: Need to bring this logic back in
-
-    #      if ($self->_isLimited && (! $self->{'looking_at_effective_id'})) {
-    #         $self->SUPER::Limit( FIELD => 'EffectiveId',
-    #               OPERATOR => '=',
-    #               QUOTEVALUE => 0,
-    #               VALUE => 'main.id');   #TODO, we shouldn't be hard coding the tablename to main.
-    #       }
-    # --- This is hardcoded above.  This comment block can probably go.
-    # Or, we need to reimplement the looking_at_effective_id toggle.
-
-    # Unless we've explicitly asked to look at a specific Type, we need
-    # to limit to it.
-    unless ( $self->{looking_at_type} ) {
-        $self->SUPER::Limit( FIELD => 'Type', VALUE => 'ticket' );
+    unless ( $self->{_sql_looking_at}{type} ) {
+        $self->Limit( FIELD => 'Type', VALUE => 'ticket' );
     }
 
     # We don't want deleted tickets unless 'allow_deleted_search' is set

commit c6be454efe6d107ad5a995839bf95caced0f1e73
Author: Alex Vandiver <alexmv at bestpractical.com>
Date:   Fri Jan 11 07:20:04 2013 -0500

    Merge remaining functions from Tickets_SQL.pm into Tickets.pm

diff --git a/lib/RT/Tickets.pm b/lib/RT/Tickets.pm
index b261c47..7137959 100644
--- a/lib/RT/Tickets.pm
+++ b/lib/RT/Tickets.pm
@@ -87,6 +87,7 @@ use Role::Basic 'with';
 with 'RT::Role::SearchBuilder::Roles';
 
 use RT::Ticket;
+use RT::SQL;
 
 sub Table { 'Tickets'}
 
@@ -222,14 +223,7 @@ my %DefaultEA = (
     CUSTOMFIELD => 'OR',
 );
 
-# Helper functions for passing the above lexically scoped tables above
-# into Tickets_SQL.
 sub FIELDS     { return \%FIELD_METADATA }
-sub dispatch   { return \%dispatch }
-
-# Bring in the clowns.
-require RT::Tickets_SQL;
-
 
 our @SORTFIELDS = qw(id Status
     Queue Subject
@@ -1630,7 +1624,7 @@ sub OrderByCols {
             next;
         }
         if ( $row->{FIELD} !~ /\./ ) {
-            my $meta = $self->FIELDS->{ $row->{FIELD} };
+            my $meta = $FIELD_METADATA{ $row->{FIELD} };
             unless ( $meta ) {
                 push @res, $row;
                 next;
@@ -1663,7 +1657,7 @@ sub OrderByCols {
         }
 
         my ( $field, $subkey ) = split /\./, $row->{FIELD}, 2;
-        my $meta = $self->FIELDS->{$field};
+        my $meta = $FIELD_METADATA{$field};
         if ( defined $meta->[0] && $meta->[0] eq 'WATCHERFIELD' ) {
             # cache alias as we want to use one alias per watcher type for sorting
             my $users = $self->{_sql_u_watchers_alias_for_sort}{ $meta->[1] };
@@ -1756,6 +1750,33 @@ sub OrderByCols {
 }
 
 
+# All SQL stuff goes into one SB subclause so we can deal with all
+# the aggregation
+sub _SQLLimit {
+    my $self = shift;
+    my %args = (@_);
+    $self->Limit(
+        %args,
+        SUBCLAUSE => 'ticketsql'
+    );
+}
+
+sub _SQLJoin {
+    my $self = shift;
+    $self->SUPER::Join(
+        @_,
+        SUBCLAUSE => 'ticketsql'
+    );
+}
+
+sub _OpenParen {
+    $_[0]->SUPER::_OpenParen( 'ticketsql' );
+}
+sub _CloseParen {
+    $_[0]->SUPER::_CloseParen( 'ticketsql' );
+}
+
+
 sub Limit {
     my $self = shift;
     my %args = @_;
@@ -1939,7 +1960,7 @@ sub IgnoreType {
 
     # Instead of faking a Limit that later gets ignored, fake up the
     # fact that we're already looking at type, so that the check in
-    # Tickets_SQL/FromSQL goes down the right branch
+    # FromSQL goes down the right branch
 
     #  $self->LimitType(VALUE => '__any');
     $self->{_sql_looking_at}{type} = 1;
@@ -2665,8 +2686,19 @@ sub _Init {
     delete $self->{'columns_to_display'};
     $self->SUPER::_Init(@_);
 
-    $self->_InitSQL;
+    $self->_InitSQL();
+}
 
+sub _InitSQL {
+    my $self = shift;
+    # Private Member Variables (which should get cleaned)
+    $self->{'_sql_transalias'}    = undef;
+    $self->{'_sql_trattachalias'} = undef;
+    $self->{'_sql_cf_alias'}  = undef;
+    $self->{'_sql_object_cfv_alias'}  = undef;
+    $self->{'_sql_watcher_join_users_alias'} = undef;
+    $self->{'_sql_query'}         = '';
+    $self->{'_sql_looking_at'}    = {};
 }
 
 
@@ -3201,14 +3233,32 @@ sub _RestrictionsToClauses {
     return \%clause;
 }
 
+=head2 ClausesToSQL
 
+=cut
 
-=head2 _ProcessRestrictions PARAMHASH
+sub ClausesToSQL {
+  my $self = shift;
+  my $clauses = shift;
+  my @sql;
 
-# The new _ProcessRestrictions is somewhat dependent on the SQL stuff,
-# but isn't quite generic enough to move into Tickets_SQL.
+  for my $f (keys %{$clauses}) {
+    my $sql;
+    my $first = 1;
 
-=cut
+    # Build SQL from the data hash
+    for my $data ( @{ $clauses->{$f} } ) {
+      $sql .= $data->[0] unless $first; $first=0; # ENTRYAGGREGATOR
+      $sql .= " '". $data->[2] . "' ";            # FIELD
+      $sql .= $data->[3] . " ";                   # OPERATOR
+      $sql .= "'". $data->[4] . "' ";             # VALUE
+    }
+
+    push @sql, " ( " . $sql . " ) ";
+  }
+
+  return join("AND", at sql);
+}
 
 sub _ProcessRestrictions {
     my $self = shift;
@@ -3222,7 +3272,7 @@ sub _ProcessRestrictions {
     delete $self->{'rows'};
     delete $self->{'count_all'};
 
-    my $sql = $self->Query;    # Violating the _SQL namespace
+    my $sql = $self->Query;
     if ( !$sql || $self->{'RecalcTicketLimits'} ) {
 
         local $self->{using_restrictions};
@@ -3336,6 +3386,121 @@ BUG: There should be an API for this
 
 =cut
 
+=head2 FromSQL
+
+Convert a RT-SQL string into a set of SearchBuilder restrictions.
+
+Returns (1, 'Status message') on success and (0, 'Error Message') on
+failure.
+
+=cut
+
+sub _parser {
+    my ($self,$string) = @_;
+    my $ea = '';
+
+    # Lower Case version of %FIELD_METADATA, for case insensitivity
+    my %lcfields = map { ( lc($_) => $_ ) } (keys %FIELD_METADATA);
+
+    my %callback;
+    $callback{'OpenParen'} = sub {
+      $self->_OpenParen
+    };
+    $callback{'CloseParen'} = sub {
+      $self->_CloseParen;
+    };
+    $callback{'EntryAggregator'} = sub { $ea = $_[0] || '' };
+    $callback{'Condition'} = sub {
+        my ($key, $op, $value) = @_;
+
+        # key has dot then it's compound variant and we have subkey
+        my $subkey = '';
+        ($key, $subkey) = ($1, $2) if $key =~ /^([^\.]+)\.(.+)$/;
+
+        # normalize key and get class (type)
+        my $class;
+        if (exists $lcfields{lc $key}) {
+            $key = $lcfields{lc $key};
+            $class = $FIELD_METADATA{$key}->[0];
+        }
+        die "Unknown field '$key' in '$string'" unless $class;
+
+        # replace __CurrentUser__ with id
+        $value = $self->CurrentUser->id if $value eq '__CurrentUser__';
+
+
+        unless( $dispatch{ $class } ) {
+            die "No dispatch method for class '$class'"
+        }
+        my $sub = $dispatch{ $class };
+
+        $sub->( $self, $key, $op, $value,
+                ENTRYAGGREGATOR => $ea,
+                SUBKEY          => $subkey,
+              );
+        $ea = '';
+    };
+    RT::SQL::Parse($string, \%callback);
+}
+
+sub FromSQL {
+    my ($self,$query) = @_;
+
+    {
+        # preserve first_row and show_rows across the CleanSlate
+        local ($self->{'first_row'}, $self->{'show_rows'}, $self->{_sql_looking_at});
+        $self->CleanSlate;
+        $self->_InitSQL();
+    }
+
+    return (1, $self->loc("No Query")) unless $query;
+
+    $self->{_sql_query} = $query;
+    eval { $self->_parser( $query ); };
+    if ( $@ ) {
+        $RT::Logger->error( $@ );
+        return (0, $@);
+    }
+
+    # We only want to look at EffectiveId's (mostly) for these searches.
+    unless ( $self->{_sql_looking_at}{effectiveid} ) {
+        $self->Limit(
+            FIELD           => 'EffectiveId',
+            VALUE           => 'main.id',
+            ENTRYAGGREGATOR => 'AND',
+            QUOTEVALUE      => 0,
+        );
+    }
+    unless ( $self->{_sql_looking_at}{type} ) {
+        $self->Limit( FIELD => 'Type', VALUE => 'ticket' );
+    }
+
+    # We don't want deleted tickets unless 'allow_deleted_search' is set
+    unless( $self->{'allow_deleted_search'} ) {
+        $self->Limit(
+            FIELD    => 'Status',
+            OPERATOR => '!=',
+            VALUE => 'deleted',
+        );
+    }
+
+    # set SB's dirty flag
+    $self->{'must_redo_search'} = 1;
+    $self->{'RecalcTicketLimits'} = 0;
+
+    return (1, $self->loc("Valid Query"));
+}
+
+=head2 Query
+
+Returns the last string passed to L</FromSQL>.
+
+=cut
+
+sub Query {
+    my $self = shift;
+    return $self->{_sql_query};
+}
 
 
 =head2 NewItem
diff --git a/lib/RT/Tickets_SQL.pm b/lib/RT/Tickets_SQL.pm
deleted file mode 100644
index 67b6e07..0000000
--- a/lib/RT/Tickets_SQL.pm
+++ /dev/null
@@ -1,313 +0,0 @@
-# BEGIN BPS TAGGED BLOCK {{{
-#
-# COPYRIGHT:
-#
-# This software is Copyright (c) 1996-2012 Best Practical Solutions, LLC
-#                                          <sales at bestpractical.com>
-#
-# (Except where explicitly superseded by other copyright notices)
-#
-#
-# LICENSE:
-#
-# This work is made available to you under the terms of Version 2 of
-# the GNU General Public License. A copy of that license should have
-# been provided with this software, but in any event can be snarfed
-# from www.gnu.org.
-#
-# This work is distributed in the hope that it will be useful, but
-# WITHOUT ANY WARRANTY; without even the implied warranty of
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-# General Public License for more details.
-#
-# You should have received a copy of the GNU General Public License
-# along with this program; if not, write to the Free Software
-# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
-# 02110-1301 or visit their web page on the internet at
-# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
-#
-#
-# CONTRIBUTION SUBMISSION POLICY:
-#
-# (The following paragraph is not intended to limit the rights granted
-# to you to modify and distribute this software under the terms of
-# the GNU General Public License and is only of importance to you if
-# you choose to contribute your changes and enhancements to the
-# community by submitting them to Best Practical Solutions, LLC.)
-#
-# By intentionally submitting any modifications, corrections or
-# derivatives to this work, or any other work intended for use with
-# Request Tracker, to Best Practical Solutions, LLC, you confirm that
-# you are the copyright holder for those contributions and you grant
-# Best Practical Solutions,  LLC a nonexclusive, worldwide, irrevocable,
-# royalty-free, perpetual, license to use, copy, create derivative
-# works based on those contributions, and sublicense and distribute
-# those contributions and any derivatives thereof.
-#
-# END BPS TAGGED BLOCK }}}
-
-package RT::Tickets;
-
-use strict;
-use warnings;
-
-
-use RT::SQL;
-
-# Import configuration data from the lexcial scope of __PACKAGE__ (or
-# at least where those two Subroutines are defined.)
-
-our (%FIELD_METADATA, %dispatch);
-
-# Lower Case version of FIELDS, for case insensitivity
-my %lcfields = map { ( lc($_) => $_ ) } (keys %FIELD_METADATA);
-
-sub _InitSQL {
-  my $self = shift;
-
-  # Private Member Variables (which should get cleaned)
-  $self->{'_sql_transalias'}    = undef;
-  $self->{'_sql_trattachalias'} = undef;
-  $self->{'_sql_cf_alias'}  = undef;
-  $self->{'_sql_object_cfv_alias'}  = undef;
-  $self->{'_sql_watcher_join_users_alias'} = undef;
-  $self->{'_sql_query'}         = '';
-  $self->{'_sql_looking_at'}    = {};
-}
-
-sub _SQLLimit {
-  my $self = shift;
-    my %args = (@_);
-
-  # All SQL stuff goes into one SB subclause so we can deal with all
-  # the aggregation
-  $self->Limit(%args,
-                      SUBCLAUSE => 'ticketsql');
-}
-
-sub _SQLJoin {
-  # All SQL stuff goes into one SB subclause so we can deal with all
-  # the aggregation
-  my $this = shift;
-
-  $this->SUPER::Join(@_,
-		     SUBCLAUSE => 'ticketsql');
-}
-
-# Helpers
-sub _OpenParen {
-  $_[0]->SUPER::_OpenParen( 'ticketsql' );
-}
-sub _CloseParen {
-  $_[0]->SUPER::_CloseParen( 'ticketsql' );
-}
-
-=head1 SQL Functions
-
-=cut
-
-=head2 Robert's Simple SQL Parser
-
-Documentation In Progress
-
-The Parser/Tokenizer is a relatively simple state machine that scans through a SQL WHERE clause type string extracting a token at a time (where a token is:
-
-  VALUE -> quoted string or number
-  AGGREGator -> AND or OR
-  KEYWORD -> quoted string or single word
-  OPerator -> =,!=,LIKE,etc..
-  PARENthesis -> open or close.
-
-And that stream of tokens is passed through the "machine" in order to build up a structure that looks like:
-
-       KEY OP VALUE
-  AND  KEY OP VALUE
-  OR   KEY OP VALUE
-
-That also deals with parenthesis for nesting.  (The parentheses are
-just handed off the SearchBuilder)
-
-=cut
-
-sub _parser {
-    my ($self,$string) = @_;
-    my $ea = '';
-
-    my %callback;
-    $callback{'OpenParen'} = sub {
-      $self->_OpenParen
-    };
-    $callback{'CloseParen'} = sub {
-      $self->_CloseParen;
-    };
-    $callback{'EntryAggregator'} = sub { $ea = $_[0] || '' };
-    $callback{'Condition'} = sub {
-        my ($key, $op, $value) = @_;
-
-        # key has dot then it's compound variant and we have subkey
-        my $subkey = '';
-        ($key, $subkey) = ($1, $2) if $key =~ /^([^\.]+)\.(.+)$/;
-
-        # normalize key and get class (type)
-        my $class;
-        if (exists $lcfields{lc $key}) {
-            $key = $lcfields{lc $key};
-            $class = $FIELD_METADATA{$key}->[0];
-        }
-        die "Unknown field '$key' in '$string'" unless $class;
-
-        # replace __CurrentUser__ with id
-        $value = $self->CurrentUser->id if $value eq '__CurrentUser__';
-
-
-        unless( $dispatch{ $class } ) {
-            die "No dispatch method for class '$class'"
-        }
-        my $sub = $dispatch{ $class };
-
-        $sub->( $self, $key, $op, $value,
-                ENTRYAGGREGATOR => $ea,
-                SUBKEY          => $subkey,
-              );
-        $ea = '';
-    };
-    RT::SQL::Parse($string, \%callback);
-}
-
-=head2 ClausesToSQL
-
-=cut
-
-sub ClausesToSQL {
-  my $self = shift;
-  my $clauses = shift;
-  my @sql;
-
-  for my $f (keys %{$clauses}) {
-    my $sql;
-    my $first = 1;
-
-    # Build SQL from the data hash
-    for my $data ( @{ $clauses->{$f} } ) {
-      $sql .= $data->[0] unless $first; $first=0; # ENTRYAGGREGATOR
-      $sql .= " '". $data->[2] . "' ";            # FIELD
-      $sql .= $data->[3] . " ";                   # OPERATOR
-      $sql .= "'". $data->[4] . "' ";             # VALUE
-    }
-
-    push @sql, " ( " . $sql . " ) ";
-  }
-
-  return join("AND", at sql);
-}
-
-=head2 FromSQL
-
-Convert a RT-SQL string into a set of SearchBuilder restrictions.
-
-Returns (1, 'Status message') on success and (0, 'Error Message') on
-failure.
-
-
-
-
-=cut
-
-sub FromSQL {
-    my ($self,$query) = @_;
-
-    {
-        # preserve first_row and show_rows across the CleanSlate
-        local ($self->{'first_row'}, $self->{'show_rows'}, $self->{_sql_looking_at});
-        $self->CleanSlate;
-        $self->_InitSQL();
-    }
-
-    return (1, $self->loc("No Query")) unless $query;
-
-    $self->{_sql_query} = $query;
-    eval { $self->_parser( $query ); };
-    if ( $@ ) {
-        $RT::Logger->error( $@ );
-        return (0, $@);
-    }
-
-    # We only want to look at EffectiveId's (mostly) for these searches.
-    unless ( $self->{_sql_looking_at}{effectiveid} ) {
-        $self->Limit(
-            FIELD           => 'EffectiveId',
-            VALUE           => 'main.id',
-            ENTRYAGGREGATOR => 'AND',
-            QUOTEVALUE      => 0,
-        );
-    }
-    unless ( $self->{_sql_looking_at}{type} ) {
-        $self->Limit( FIELD => 'Type', VALUE => 'ticket' );
-    }
-
-    # We don't want deleted tickets unless 'allow_deleted_search' is set
-    unless( $self->{'allow_deleted_search'} ) {
-        $self->SUPER::Limit( FIELD    => 'Status',
-                             OPERATOR => '!=',
-                             VALUE => 'deleted',
-                           );
-    }
-
-    # set SB's dirty flag
-    $self->{'must_redo_search'} = 1;
-    $self->{'RecalcTicketLimits'} = 0;                                           
-
-    return (1, $self->loc("Valid Query"));
-}
-
-=head2 Query
-
-Returns the query that this object was initialized with
-
-=cut
-
-sub Query {
-    return ($_[0]->{_sql_query});
-}
-
-1;
-
-=pod
-
-=head2 Exceptions
-
-Most of the RT code does not use Exceptions (die/eval) but it is used
-in the TicketSQL code for simplicity and historical reasons.  Lest you
-be worried that the dies will trigger user visible errors, all are
-trapped via evals.
-
-99% of the dies fall in subroutines called via FromSQL and then parse.
-(This includes all of the _FooLimit routines in Tickets_Overlay.pm.)
-The other 1% or so are via _ProcessRestrictions.
-
-All dies are trapped by eval {}s, and will be logged at the 'error'
-log level.  The general failure mode is to not display any tickets.
-
-=head2 General Flow
-
-Legacy Layer:
-
-   Legacy LimitFoo routines build up a RestrictionsHash
-
-   _ProcessRestrictions converts the Restrictions to Clauses
-   ([key,op,val,rest]).
-
-   Clauses are converted to RT-SQL (TicketSQL)
-
-New RT-SQL Layer:
-
-   FromSQL calls the parser
-
-   The parser calls the _FooLimit routines to do DBIx::SearchBuilder
-   limits.
-
-And then the normal SearchBuilder/Ticket routines are used for
-display/navigation.
-
-=cut
-
diff --git a/share/html/Search/Build.html b/share/html/Search/Build.html
index 3709bf3..1d743af 100644
--- a/share/html/Search/Build.html
+++ b/share/html/Search/Build.html
@@ -53,7 +53,7 @@
 %#   Build/Edit.html (Advanced).)
 %#
 %#   After doing some stuff with default arguments and saved searches, the ParseQuery
-%#   function (which is similar to, but not the same as, _parser in lib/RT/Tickets_SQL.pm)
+%#   function (which is similar to, but not the same as, _parser in lib/RT/Tickets.pm)
 %#   converts the Query into a RT::Interface::Web::QueryBuilder::Tree.  This mason file
 %#   then adds stuff to or modifies the tree based on the actions that had been requested
 %#   by clicking buttons.  It then calls GetQueryAndOptionList on the tree to generate

commit 912339206a5727bc196f096f1d92e759d1c4dd64
Author: Alex Vandiver <alexmv at bestpractical.com>
Date:   Fri Jan 11 08:07:57 2013 -0500

    The Join method ignores SUBCLAUSE; deprecate _SQLJoin in favor of Join

diff --git a/lib/RT/Tickets.pm b/lib/RT/Tickets.pm
index 7137959..2b95313 100644
--- a/lib/RT/Tickets.pm
+++ b/lib/RT/Tickets.pm
@@ -692,7 +692,7 @@ sub _TransLimit {
 
     my $txn_alias = $self->JoinTransactions;
     unless ( defined $self->{_sql_trattachalias} ) {
-        $self->{_sql_trattachalias} = $self->_SQLJoin(
+        $self->{_sql_trattachalias} = $self->Join(
             TYPE   => 'LEFT', # not all txns have an attachment
             ALIAS1 => $txn_alias,
             FIELD1 => 'id',
@@ -762,7 +762,7 @@ sub _TransContentLimit {
 
     my $txn_alias = $self->JoinTransactions;
     unless ( defined $self->{_sql_trattachalias} ) {
-        $self->{_sql_trattachalias} = $self->_SQLJoin(
+        $self->{_sql_trattachalias} = $self->Join(
             TYPE   => 'LEFT', # not all txns have an attachment
             ALIAS1 => $txn_alias,
             FIELD1 => 'id',
@@ -777,7 +777,7 @@ sub _TransContentLimit {
 
         my $alias;
         if ( $config->{'Table'} and $config->{'Table'} ne "Attachments") {
-            $alias = $self->{'_sql_aliases'}{'full_text'} ||= $self->_SQLJoin(
+            $alias = $self->{'_sql_aliases'}{'full_text'} ||= $self->Join(
                 TYPE   => 'LEFT',
                 ALIAS1 => $self->{'_sql_trattachalias'},
                 FIELD1 => 'id',
@@ -1760,13 +1760,10 @@ sub _SQLLimit {
         SUBCLAUSE => 'ticketsql'
     );
 }
-
 sub _SQLJoin {
     my $self = shift;
-    $self->SUPER::Join(
-        @_,
-        SUBCLAUSE => 'ticketsql'
-    );
+    RT->Deprecated( Remove => "4.4", Instead => "Join" );
+    $self->Join(@_);
 }
 
 sub _OpenParen {

commit 4f61730bb99b607c81bf52ab160762c138fbd070
Author: Alex Vandiver <alexmv at bestpractical.com>
Date:   Fri Jan 11 08:09:39 2013 -0500

    Restrict SUBCLAUSE lexically during parsing, and switch to simple Limit
    
    Now that Limit functions as every other DBIx::SearchBuilder class, it is
    no longer necessary to call SUPER::Limit.  Additionally, the use of the
    confusing _SQLLimit method can be avoided by lexically setting the
    default subclause during parsing in FromSQL.  This obviates the need to
    remember the difference between the two methods.
    
    Deprecate the old _SQLLimit for future removal.

diff --git a/lib/RT/Role/SearchBuilder/Roles.pm b/lib/RT/Role/SearchBuilder/Roles.pm
index 7eb61a9..bcbcdae 100644
--- a/lib/RT/Role/SearchBuilder/Roles.pm
+++ b/lib/RT/Role/SearchBuilder/Roles.pm
@@ -128,7 +128,7 @@ sub _GroupMembersJoin {
         ENTRYAGGREGATOR => 'AND',
     );
     $self->Limit(
-        $args{'Left'} ? (LEFTJOIN => $alias) : (),
+        LEFTJOIN => $alias,
         ALIAS => $alias,
         FIELD => 'Disabled',
         VALUE => 0,
diff --git a/lib/RT/Tickets.pm b/lib/RT/Tickets.pm
index 2b95313..8f84cef 100644
--- a/lib/RT/Tickets.pm
+++ b/lib/RT/Tickets.pm
@@ -299,7 +299,7 @@ sub _BookmarkLimit {
 
     my @bookmarks = $sb->CurrentUser->UserObj->Bookmarks;
 
-    return $sb->_SQLLimit(
+    return $sb->Limit(
         FIELD    => $field,
         OPERATOR => $op,
         VALUE    => 0,
@@ -319,7 +319,7 @@ sub _BookmarkLimit {
     my $first = 1;
     my $ea = $op eq '='? 'OR': 'AND';
     foreach my $id ( sort @bookmarks ) {
-        $sb->_SQLLimit(
+        $sb->Limit(
             ALIAS    => $tickets_alias,
             FIELD    => 'id',
             OPERATOR => $op,
@@ -365,7 +365,7 @@ sub _EnumLimit {
         $o->Load($value);
         $value = $o->Id;
     }
-    $sb->_SQLLimit(
+    $sb->Limit(
         FIELD    => $field,
         VALUE    => $value,
         OPERATOR => $op,
@@ -389,7 +389,7 @@ sub _IntLimit {
     die "Invalid Operator $op for $field"
         unless $op =~ /^(=|!=|>|<|>=|<=)$/;
 
-    $sb->_SQLLimit(
+    $sb->Limit(
         FIELD    => $field,
         VALUE    => $value,
         OPERATOR => $op,
@@ -468,13 +468,13 @@ sub _LinkLimit {
             TABLE2 => 'Links',
             FIELD2 => 'Local' . $linkfield
         );
-        $sb->SUPER::Limit(
+        $sb->Limit(
             LEFTJOIN => $linkalias,
             FIELD    => 'Type',
             OPERATOR => '=',
             VALUE    => $meta->[2],
         ) if $meta->[2];
-        $sb->_SQLLimit(
+        $sb->Limit(
             @rest,
             ALIAS      => $linkalias,
             FIELD      => $matchfield,
@@ -491,19 +491,19 @@ sub _LinkLimit {
             TABLE2 => 'Links',
             FIELD2 => 'Local' . $linkfield
         );
-        $sb->SUPER::Limit(
+        $sb->Limit(
             LEFTJOIN => $linkalias,
             FIELD    => 'Type',
             OPERATOR => '=',
             VALUE    => $meta->[2],
         ) if $meta->[2];
-        $sb->SUPER::Limit(
+        $sb->Limit(
             LEFTJOIN => $linkalias,
             FIELD    => $matchfield,
             OPERATOR => '=',
             VALUE    => $value,
         );
-        $sb->_SQLLimit(
+        $sb->Limit(
             @rest,
             ALIAS      => $linkalias,
             FIELD      => $matchfield,
@@ -549,14 +549,14 @@ sub _DateLimit {
 
         $sb->_OpenParen;
 
-        $sb->_SQLLimit(
+        $sb->Limit(
             FIELD    => $meta->[1],
             OPERATOR => ">=",
             VALUE    => $daystart,
             @rest,
         );
 
-        $sb->_SQLLimit(
+        $sb->Limit(
             FIELD    => $meta->[1],
             OPERATOR => "<",
             VALUE    => $dayend,
@@ -568,7 +568,7 @@ sub _DateLimit {
 
     }
     else {
-        $sb->_SQLLimit(
+        $sb->Limit(
             FIELD    => $meta->[1],
             OPERATOR => $op,
             VALUE    => $date->ISO,
@@ -604,7 +604,7 @@ sub _StringLimit {
         $value = 'NULL';
     }
 
-    $sb->_SQLLimit(
+    $sb->Limit(
         FIELD         => $field,
         OPERATOR      => $op,
         VALUE         => $value,
@@ -647,14 +647,14 @@ sub _TransDateLimit {
         $date->AddDay;
         my $dayend = $date->ISO;
 
-        $sb->_SQLLimit(
+        $sb->Limit(
             ALIAS         => $txn_alias,
             FIELD         => 'Created',
             OPERATOR      => ">=",
             VALUE         => $daystart,
             @rest
         );
-        $sb->_SQLLimit(
+        $sb->Limit(
             ALIAS         => $txn_alias,
             FIELD         => 'Created',
             OPERATOR      => "<=",
@@ -669,7 +669,7 @@ sub _TransDateLimit {
     else {
 
         #Search for the right field
-        $sb->_SQLLimit(
+        $sb->Limit(
             ALIAS         => $txn_alias,
             FIELD         => 'Created',
             OPERATOR      => $op,
@@ -701,7 +701,7 @@ sub _TransLimit {
         );
     }
 
-    $self->_SQLLimit(
+    $self->Limit(
         %rest,
         ALIAS         => $self->{_sql_trattachalias},
         FIELD         => $field,
@@ -756,7 +756,7 @@ sub _TransContentLimit {
 
     my $config = RT->Config->Get('FullTextSearch') || {};
     unless ( $config->{'Enable'} ) {
-        $self->_SQLLimit( %rest, FIELD => 'id', VALUE => 0 );
+        $self->Limit( %rest, FIELD => 'id', VALUE => 0 );
         return;
     }
 
@@ -793,7 +793,7 @@ sub _TransContentLimit {
         if ( $db_type eq 'Oracle' ) {
             my $dbh = $RT::Handle->dbh;
             my $alias = $self->{_sql_trattachalias};
-            $self->_SQLLimit(
+            $self->Limit(
                 %rest,
                 FUNCTION      => "CONTAINS( $alias.$field, ".$dbh->quote($value) .")",
                 OPERATOR      => '>',
@@ -803,7 +803,7 @@ sub _TransContentLimit {
             );
             # this is required to trick DBIx::SB's LEFT JOINS optimizer
             # into deciding that join is redundant as it is
-            $self->_SQLLimit(
+            $self->Limit(
                 ENTRYAGGREGATOR => 'AND',
                 ALIAS           => $self->{_sql_trattachalias},
                 FIELD           => 'Content',
@@ -813,7 +813,7 @@ sub _TransContentLimit {
         }
         elsif ( $db_type eq 'Pg' ) {
             my $dbh = $RT::Handle->dbh;
-            $self->_SQLLimit(
+            $self->Limit(
                 %rest,
                 ALIAS       => $alias,
                 FIELD       => $index,
@@ -837,7 +837,7 @@ sub _TransContentLimit {
             $value =~ s/;/\\;/g;
 
             my $max = $config->{'MaxMatches'};
-            $self->_SQLLimit(
+            $self->Limit(
                 %rest,
                 ALIAS       => $alias,
                 FIELD       => 'query',
@@ -846,7 +846,7 @@ sub _TransContentLimit {
             );
         }
     } else {
-        $self->_SQLLimit(
+        $self->Limit(
             %rest,
             ALIAS         => $self->{_sql_trattachalias},
             FIELD         => $field,
@@ -856,7 +856,7 @@ sub _TransContentLimit {
         );
     }
     if ( RT->Config->Get('DontSearchFileAttachments') ) {
-        $self->_SQLLimit(
+        $self->Limit(
             ENTRYAGGREGATOR => 'AND',
             ALIAS           => $self->{_sql_trattachalias},
             FIELD           => 'Filename',
@@ -956,7 +956,7 @@ sub _WatcherMembershipLimit {
     my $users        = $self->NewAlias('Users');
     my $memberships  = $self->NewAlias('CachedGroupMembers');
 
-    $self->_SQLLimit(
+    $self->Limit(
         ALIAS    => $memberships,
         FIELD    => 'GroupId',
         VALUE    => $value,
@@ -965,7 +965,7 @@ sub _WatcherMembershipLimit {
     );
 
     # Tie to groups for tickets we care about
-    $self->_SQLLimit(
+    $self->Limit(
         ALIAS           => $groups,
         FIELD           => 'Domain',
         VALUE           => 'RT::Ticket-Role',
@@ -986,7 +986,7 @@ sub _WatcherMembershipLimit {
     my $type = ( defined $meta->[1] ? $meta->[1] : undef );
 
     if ($type) {
-        $self->_SQLLimit(
+        $self->Limit(
             ALIAS           => $groups,
             FIELD           => 'Type',
             VALUE           => $type,
@@ -1105,7 +1105,7 @@ sub _CustomFieldJoin {
             TABLE2 => 'ObjectCustomFieldValues',
             FIELD2 => 'ObjectId',
         );
-        $self->SUPER::Limit(
+        $self->Limit(
             LEFTJOIN        => $TicketCFs,
             FIELD           => 'CustomField',
             VALUE           => $cfid,
@@ -1120,7 +1120,7 @@ sub _CustomFieldJoin {
             FIELD2     => 'ObjectId',
         );
 
-        $self->SUPER::Limit(
+        $self->Limit(
             LEFTJOIN        => $ocfalias,
             ENTRYAGGREGATOR => 'OR',
             FIELD           => 'ObjectId',
@@ -1134,13 +1134,13 @@ sub _CustomFieldJoin {
             TABLE2     => 'CustomFields',
             FIELD2     => 'id',
         );
-        $self->SUPER::Limit(
+        $self->Limit(
             LEFTJOIN        => $CFs,
             ENTRYAGGREGATOR => 'AND',
             FIELD           => 'LookupType',
             VALUE           => 'RT::Queue-RT::Ticket',
         );
-        $self->SUPER::Limit(
+        $self->Limit(
             LEFTJOIN        => $CFs,
             ENTRYAGGREGATOR => 'AND',
             FIELD           => 'Name',
@@ -1154,7 +1154,7 @@ sub _CustomFieldJoin {
             TABLE2 => 'ObjectCustomFieldValues',
             FIELD2 => 'CustomField',
         );
-        $self->SUPER::Limit(
+        $self->Limit(
             LEFTJOIN        => $TicketCFs,
             FIELD           => 'ObjectId',
             VALUE           => 'main.id',
@@ -1162,13 +1162,13 @@ sub _CustomFieldJoin {
             ENTRYAGGREGATOR => 'AND',
         );
     }
-    $self->SUPER::Limit(
+    $self->Limit(
         LEFTJOIN        => $TicketCFs,
         FIELD           => 'ObjectType',
         VALUE           => 'RT::Ticket',
         ENTRYAGGREGATOR => 'AND'
     );
-    $self->SUPER::Limit(
+    $self->Limit(
         LEFTJOIN        => $TicketCFs,
         FIELD           => 'Disabled',
         OPERATOR        => '=',
@@ -1281,14 +1281,14 @@ sub _CustomFieldLimit {
         # with column specified we have different situation
         my ($TicketCFs, $CFs) = $self->_CustomFieldJoin( $cfkey, $cfid, $field );
         $self->_OpenParen;
-        $self->_SQLLimit(
+        $self->Limit(
             ALIAS    => $TicketCFs,
             FIELD    => 'id',
             OPERATOR => $op,
             VALUE    => $value,
             %rest
         );
-        $self->_SQLLimit(
+        $self->Limit(
             ALIAS      => $CFs,
             FIELD      => 'Name',
             OPERATOR   => 'IS NOT',
@@ -1352,7 +1352,7 @@ sub _CustomFieldLimit {
         # if column is defined then deal only with it
         # otherwise search in Content and in LargeContent
         if ( $column ) {
-            $self->_SQLLimit( $fix_op->(
+            $self->Limit( $fix_op->(
                 ALIAS      => $TicketCFs,
                 FIELD      => $column,
                 OPERATOR   => $op,
@@ -1372,7 +1372,7 @@ sub _CustomFieldLimit {
                     # there is time speccified.
                     my $date = RT::Date->new( $self->CurrentUser );
                     $date->Set( Format => 'unknown', Value => $value );
-                    $self->_SQLLimit(
+                    $self->Limit(
                         ALIAS    => $TicketCFs,
                         FIELD    => 'Content',
                         OPERATOR => "=",
@@ -1393,7 +1393,7 @@ sub _CustomFieldLimit {
 
                     $self->_OpenParen;
 
-                    $self->_SQLLimit(
+                    $self->Limit(
                         ALIAS    => $TicketCFs,
                         FIELD    => 'Content',
                         OPERATOR => ">=",
@@ -1401,7 +1401,7 @@ sub _CustomFieldLimit {
                         %rest,
                     );
 
-                    $self->_SQLLimit(
+                    $self->Limit(
                         ALIAS    => $TicketCFs,
                         FIELD    => 'Content',
                         OPERATOR => "<=",
@@ -1415,7 +1415,7 @@ sub _CustomFieldLimit {
             }
             elsif ( $op eq '=' || $op eq '!=' || $op eq '<>' ) {
                 if ( length( Encode::encode_utf8($value) ) < 256 ) {
-                    $self->_SQLLimit(
+                    $self->Limit(
                         ALIAS    => $TicketCFs,
                         FIELD    => 'Content',
                         OPERATOR => $op,
@@ -1426,14 +1426,14 @@ sub _CustomFieldLimit {
                 }
                 else {
                     $self->_OpenParen;
-                    $self->_SQLLimit(
+                    $self->Limit(
                         ALIAS           => $TicketCFs,
                         FIELD           => 'Content',
                         OPERATOR        => '=',
                         VALUE           => '',
                         ENTRYAGGREGATOR => 'OR'
                     );
-                    $self->_SQLLimit(
+                    $self->Limit(
                         ALIAS           => $TicketCFs,
                         FIELD           => 'Content',
                         OPERATOR        => 'IS',
@@ -1441,7 +1441,7 @@ sub _CustomFieldLimit {
                         ENTRYAGGREGATOR => 'OR'
                     );
                     $self->_CloseParen;
-                    $self->_SQLLimit( $fix_op->(
+                    $self->Limit( $fix_op->(
                         ALIAS           => $TicketCFs,
                         FIELD           => 'LargeContent',
                         OPERATOR        => $op,
@@ -1452,7 +1452,7 @@ sub _CustomFieldLimit {
                 }
             }
             else {
-                $self->_SQLLimit(
+                $self->Limit(
                     ALIAS    => $TicketCFs,
                     FIELD    => 'Content',
                     OPERATOR => $op,
@@ -1463,14 +1463,14 @@ sub _CustomFieldLimit {
 
                 $self->_OpenParen;
                 $self->_OpenParen;
-                $self->_SQLLimit(
+                $self->Limit(
                     ALIAS           => $TicketCFs,
                     FIELD           => 'Content',
                     OPERATOR        => '=',
                     VALUE           => '',
                     ENTRYAGGREGATOR => 'OR'
                 );
-                $self->_SQLLimit(
+                $self->Limit(
                     ALIAS           => $TicketCFs,
                     FIELD           => 'Content',
                     OPERATOR        => 'IS',
@@ -1478,7 +1478,7 @@ sub _CustomFieldLimit {
                     ENTRYAGGREGATOR => 'OR'
                 );
                 $self->_CloseParen;
-                $self->_SQLLimit( $fix_op->(
+                $self->Limit( $fix_op->(
                     ALIAS           => $TicketCFs,
                     FIELD           => 'LargeContent',
                     OPERATOR        => $op,
@@ -1501,7 +1501,7 @@ sub _CustomFieldLimit {
             # TODO: reorder joins T <- OCFVs <- CFs <- OCFs if
             # we want treat IS NULL as (not applies or has
             # no value)
-            $self->_SQLLimit(
+            $self->Limit(
                 ALIAS           => $CFs,
                 FIELD           => 'Name',
                 OPERATOR        => 'IS NOT',
@@ -1512,7 +1512,7 @@ sub _CustomFieldLimit {
             $self->_CloseParen;
 
             if ($negative_op) {
-                $self->_SQLLimit(
+                $self->Limit(
                     ALIAS           => $TicketCFs,
                     FIELD           => $column || 'Content',
                     OPERATOR        => 'IS',
@@ -1535,7 +1535,7 @@ sub _CustomFieldLimit {
         # if column is defined then deal only with it
         # otherwise search in Content and in LargeContent
         if ( $column ) {
-            $self->SUPER::Limit( $fix_op->(
+            $self->Limit( $fix_op->(
                 LEFTJOIN   => $TicketCFs,
                 ALIAS      => $TicketCFs,
                 FIELD      => $column,
@@ -1545,7 +1545,7 @@ sub _CustomFieldLimit {
             ) );
         }
         else {
-            $self->SUPER::Limit(
+            $self->Limit(
                 LEFTJOIN   => $TicketCFs,
                 ALIAS      => $TicketCFs,
                 FIELD      => 'Content',
@@ -1554,7 +1554,7 @@ sub _CustomFieldLimit {
                 CASESENSITIVE => 0,
             );
         }
-        $self->_SQLLimit(
+        $self->Limit(
             %rest,
             ALIAS      => $TicketCFs,
             FIELD      => 'id',
@@ -1575,20 +1575,20 @@ sub _HasAttributeLimit {
         TABLE2 => 'Attributes',
         FIELD2 => 'ObjectId',
     );
-    $self->SUPER::Limit(
+    $self->Limit(
         LEFTJOIN        => $alias,
         FIELD           => 'ObjectType',
         VALUE           => 'RT::Ticket',
         ENTRYAGGREGATOR => 'AND'
     );
-    $self->SUPER::Limit(
+    $self->Limit(
         LEFTJOIN        => $alias,
         FIELD           => 'Name',
         OPERATOR        => $op,
         VALUE           => $value,
         ENTRYAGGREGATOR => 'AND'
     );
-    $self->_SQLLimit(
+    $self->Limit(
         %rest,
         ALIAS      => $alias,
         FIELD      => 'id',
@@ -1672,7 +1672,7 @@ sub OrderByCols {
            $cfkey .= ".ordering" if !$cf_obj || ($cf_obj->MaxValues||0) != 1;
            my ($TicketCFs, $CFs) = $self->_CustomFieldJoin( $cfkey, ($cf_obj ?$cf_obj->id :0) , $field );
            # this is described in _CustomFieldLimit
-           $self->_SQLLimit(
+           $self->Limit(
                ALIAS      => $CFs,
                FIELD      => 'Name',
                OPERATOR   => 'IS NOT',
@@ -1697,7 +1697,7 @@ sub OrderByCols {
                TABLE2 => 'CustomFieldValues',
                FIELD2 => 'CustomField',
            );
-           $self->SUPER::Limit(
+           $self->Limit(
                LEFTJOIN        => $CFvs,
                FIELD           => 'Name',
                QUOTEVALUE      => 0,
@@ -1749,16 +1749,10 @@ sub OrderByCols {
     return $self->SUPER::OrderByCols(@res);
 }
 
-
-# All SQL stuff goes into one SB subclause so we can deal with all
-# the aggregation
 sub _SQLLimit {
     my $self = shift;
-    my %args = (@_);
-    $self->Limit(
-        %args,
-        SUBCLAUSE => 'ticketsql'
-    );
+    RT->Deprecated( Remove => "4.4", Instead => "Limit" );
+    $self->Limit(@_);
 }
 sub _SQLJoin {
     my $self = shift;
@@ -1773,7 +1767,6 @@ sub _CloseParen {
     $_[0]->SUPER::_CloseParen( 'ticketsql' );
 }
 
-
 sub Limit {
     my $self = shift;
     my %args = @_;
@@ -1786,10 +1779,13 @@ sub Limit {
         $self->LimitField(@_);
     }
 
+    $args{SUBCLAUSE} ||= "ticketsql"
+        if $self->{parsing_ticketsql} and not $args{LEFTJOIN};
+
     $self->{_sql_looking_at}{ lc $args{FIELD} } = 1
         if (not $args{ALIAS} or $args{ALIAS} eq "main");
 
-    $self->SUPER::Limit(@_);
+    $self->SUPER::Limit(%args);
 }
 
 
@@ -2954,7 +2950,7 @@ sub CurrentUserCanSee {
     }
 
     unless ( @direct_queues || keys %roles ) {
-        $self->SUPER::Limit(
+        $self->Limit(
             SUBCLAUSE => 'ACL',
             ALIAS => 'main',
             FIELD => 'id',
@@ -2971,7 +2967,7 @@ sub CurrentUserCanSee {
         if ( $join_roles ) {
             $role_group_alias = $self->_RoleGroupsJoin( New => 1 );
             $cgm_alias = $self->_GroupMembersJoin( GroupsAlias => $role_group_alias );
-            $self->SUPER::Limit(
+            $self->Limit(
                 LEFTJOIN   => $cgm_alias,
                 FIELD      => 'MemberId',
                 OPERATOR   => '=',
@@ -2984,7 +2980,7 @@ sub CurrentUserCanSee {
 
             return unless @queues;
             if ( @queues == 1 ) {
-                $self->SUPER::Limit(
+                $self->Limit(
                     SUBCLAUSE => 'ACL',
                     ALIAS => 'main',
                     FIELD => 'Queue',
@@ -2994,7 +2990,7 @@ sub CurrentUserCanSee {
             } else {
                 $self->SUPER::_OpenParen('ACL');
                 foreach my $q ( @queues ) {
-                    $self->SUPER::Limit(
+                    $self->Limit(
                         SUBCLAUSE => 'ACL',
                         ALIAS => 'main',
                         FIELD => 'Queue',
@@ -3014,7 +3010,7 @@ sub CurrentUserCanSee {
         while ( my ($role, $queues) = each %roles ) {
             $self->SUPER::_OpenParen('ACL');
             if ( $role eq 'Owner' ) {
-                $self->SUPER::Limit(
+                $self->Limit(
                     SUBCLAUSE => 'ACL',
                     FIELD           => 'Owner',
                     VALUE           => $id,
@@ -3022,7 +3018,7 @@ sub CurrentUserCanSee {
                 );
             }
             else {
-                $self->SUPER::Limit(
+                $self->Limit(
                     SUBCLAUSE       => 'ACL',
                     ALIAS           => $cgm_alias,
                     FIELD           => 'MemberId',
@@ -3031,7 +3027,7 @@ sub CurrentUserCanSee {
                     QUOTEVALUE      => 0,
                     ENTRYAGGREGATOR => $ea,
                 );
-                $self->SUPER::Limit(
+                $self->Limit(
                     SUBCLAUSE       => 'ACL',
                     ALIAS           => $role_group_alias,
                     FIELD           => 'Type',
@@ -3453,7 +3449,10 @@ sub FromSQL {
     return (1, $self->loc("No Query")) unless $query;
 
     $self->{_sql_query} = $query;
-    eval { $self->_parser( $query ); };
+    eval {
+        local $self->{parsing_ticketsql} = 1;
+        $self->_parser( $query );
+    };
     if ( $@ ) {
         $RT::Logger->error( $@ );
         return (0, $@);

commit f9adf73b0c93d58bb04c5646bf03011dbffb68e4
Author: Alex Vandiver <alexmv at bestpractical.com>
Date:   Fri Jan 11 08:10:03 2013 -0500

    Remove unused Restriction-related methods
    
    These methods are unused and do not function as expected.  As part of
    de-emphasizing the Restrictions interface, remove them.

diff --git a/lib/RT/Tickets.pm b/lib/RT/Tickets.pm
index 8f84cef..1ba5feb 100644
--- a/lib/RT/Tickets.pm
+++ b/lib/RT/Tickets.pm
@@ -3046,58 +3046,6 @@ sub CurrentUserCanSee {
 
 
 
-
-
-=head2 LoadRestrictions
-
-LoadRestrictions takes a string which can fully populate the TicketRestrictons hash.
-TODO It is not yet implemented
-
-=cut
-
-
-
-=head2 DescribeRestrictions
-
-takes nothing.
-Returns a hash keyed by restriction id.
-Each element of the hash is currently a one element hash that contains DESCRIPTION which
-is a description of the purpose of that TicketRestriction
-
-=cut
-
-sub DescribeRestrictions {
-    my $self = shift;
-
-    my %listing;
-
-    foreach my $row ( keys %{ $self->{'TicketRestrictions'} } ) {
-        $listing{$row} = $self->{'TicketRestrictions'}{$row}{'DESCRIPTION'};
-    }
-    return (%listing);
-}
-
-
-
-=head2 RestrictionValues FIELD
-
-Takes a restriction field and returns a list of values this field is restricted
-to.
-
-=cut
-
-sub RestrictionValues {
-    my $self  = shift;
-    my $field = shift;
-    map $self->{'TicketRestrictions'}{$_}{'VALUE'}, grep {
-               $self->{'TicketRestrictions'}{$_}{'FIELD'}    eq $field
-            && $self->{'TicketRestrictions'}{$_}{'OPERATOR'} eq "="
-        }
-        keys %{ $self->{'TicketRestrictions'} };
-}
-
-
-
 =head2 ClearRestrictions
 
 Removes all restrictions irretrievably
@@ -3111,27 +3059,6 @@ sub ClearRestrictions {
     $self->{'RecalcTicketLimits'}      = 1;
 }
 
-
-
-=head2 DeleteRestriction
-
-Takes the row Id of a restriction (From DescribeRestrictions' output, for example.
-Removes that restriction from the session's limits.
-
-=cut
-
-sub DeleteRestriction {
-    my $self = shift;
-    my $row  = shift;
-    delete $self->{'TicketRestrictions'}{$row};
-
-    $self->{'RecalcTicketLimits'} = 1;
-
-    #make the underlying easysearch object forget all its preconceptions
-}
-
-
-
 # Convert a set of oldstyle SB Restrictions to Clauses for RQL
 
 sub _RestrictionsToClauses {

commit e29fc5fb72befb09b5d52bd8a749437d3ceae6b1
Author: Alex Vandiver <alexmv at bestpractical.com>
Date:   Fri Jan 11 08:13:34 2013 -0500

    TicketAliases was removed when TicketSQL came in, in f4ef4bb

diff --git a/lib/RT/Tickets.pm b/lib/RT/Tickets.pm
index 1ba5feb..bbda6ae 100644
--- a/lib/RT/Tickets.pm
+++ b/lib/RT/Tickets.pm
@@ -727,8 +727,7 @@ sub _TransContentLimit {
     #Basically, we want to make sure that the limits apply to
     #the same attachment, rather than just another attachment
     #for the same ticket, no matter how many clauses we lump
-    #on. We put them in TicketAliases so that they get nuked
-    #when we redo the join.
+    #on.
 
     # In the SQL, we might have
     #       (( Content = foo ) or ( Content = bar AND Content = baz ))
@@ -3183,9 +3182,6 @@ sub ClausesToSQL {
 sub _ProcessRestrictions {
     my $self = shift;
 
-    #Blow away ticket aliases since we'll need to regenerate them for
-    #a new search
-    delete $self->{'TicketAliases'};
     delete $self->{'items_array'};
     delete $self->{'item_map'};
     delete $self->{'raw_rows'};

commit c64e974f6c1f8eea3c17c4621935b22a3f4ae0e3
Author: Alex Vandiver <alexmv at bestpractical.com>
Date:   Fri Jan 11 08:22:03 2013 -0500

    ->{'rows'} has not been used since DBIx::SB 1.27

diff --git a/lib/RT/Links.pm b/lib/RT/Links.pm
index 52b8c8d..57aa5a9 100644
--- a/lib/RT/Links.pm
+++ b/lib/RT/Links.pm
@@ -156,7 +156,6 @@ sub AddRecord {
     return unless $self->IsValidLink($record);
 
     push @{$self->{'items'}}, $record;
-    $self->{'rows'}++;
 }
 
 =head2 IsValidLink
diff --git a/lib/RT/Report/Tickets.pm b/lib/RT/Report/Tickets.pm
index 08d6ac4..7bb4590 100644
--- a/lib/RT/Report/Tickets.pm
+++ b/lib/RT/Report/Tickets.pm
@@ -282,7 +282,6 @@ sub AddRecord {
     my $self = shift;
     my $record = shift;
     push @{$self->{'items'}}, $record;
-    $self->{'rows'}++;
 }
 
 1;
diff --git a/lib/RT/Tickets.pm b/lib/RT/Tickets.pm
index bbda6ae..69244b2 100644
--- a/lib/RT/Tickets.pm
+++ b/lib/RT/Tickets.pm
@@ -3185,7 +3185,6 @@ sub _ProcessRestrictions {
     delete $self->{'items_array'};
     delete $self->{'item_map'};
     delete $self->{'raw_rows'};
-    delete $self->{'rows'};
     delete $self->{'count_all'};
 
     my $sql = $self->Query;

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


More information about the Rt-commit mailing list