[Rt-commit] rt branch 5.0/improve-text-indexes2 created. rt-5.0.3-336-ga33069ed13

BPS Git Server git at git.bestpractical.com
Tue Mar 28 14:55:31 UTC 2023


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "rt".

The branch, 5.0/improve-text-indexes2 has been created
        at  a33069ed132e6bcf5440794572e1784b002694f6 (commit)

- Log -----------------------------------------------------------------
commit a33069ed132e6bcf5440794572e1784b002694f6
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Tue Mar 28 07:59:32 2023 +0800

    Update tests to correct lower cased system group names
    
    System groups names are case sensitive now.

diff --git a/t/security/CVE-2011-5092-datetimeformat.t b/t/security/CVE-2011-5092-datetimeformat.t
index 4af6af6e0c..66fca3f21a 100644
--- a/t/security/CVE-2011-5092-datetimeformat.t
+++ b/t/security/CVE-2011-5092-datetimeformat.t
@@ -15,7 +15,7 @@ ok $user->id, 'created user';
 
 ok(
     RT::Test->set_rights(
-        { Principal => 'privileged', Right => [qw(ModifySelf ShowTicket)] },
+        { Principal => 'Privileged', Right => [qw(ModifySelf ShowTicket)] },
     ),
     "granted ModifySelf to privileged"
 );
diff --git a/t/security/CVE-2011-5092-prefs.t b/t/security/CVE-2011-5092-prefs.t
index 347de7bfce..64041e873f 100644
--- a/t/security/CVE-2011-5092-prefs.t
+++ b/t/security/CVE-2011-5092-prefs.t
@@ -16,7 +16,7 @@ ok $user->id, 'created user';
 
 ok(
     RT::Test->set_rights(
-        { Principal => 'privileged', Right => [qw(ModifySelf ShowTicket)] },
+        { Principal => 'Privileged', Right => [qw(ModifySelf ShowTicket)] },
     ),
     "granted ModifySelf to privileged"
 );

commit d8904a4eb248b84ddf06ac19901e527f4fcccab6
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Tue Mar 28 05:20:53 2023 +0800

    Use is_case_sensitive to determine case sensitivity for LoadByCols

diff --git a/lib/RT/Record.pm b/lib/RT/Record.pm
index 6aadca72ea..44dd695691 100644
--- a/lib/RT/Record.pm
+++ b/lib/RT/Record.pm
@@ -381,7 +381,18 @@ sub LoadByCols {
     # If this database is case sensitive we need to uncase objects for
     # explicit loading
     my %hash = (@_);
+
+    my $case_insensitive_fields = $self->_CaseInsensitiveFields;
+    # User defined groups are case insensitive, others are not
+    if ( $self->isa('RT::Group') ) {
+        if ( defined $hash{Name} && ( $hash{Domain} // '' ) eq 'UserDefined' ) {
+            # override just for this call
+            $case_insensitive_fields = { %$case_insensitive_fields, Name => 1 };
+        }
+    }
+
     foreach my $key ( keys %hash ) {
+        next unless $case_insensitive_fields->{$key};
 
         # If we've been passed an empty value, we can't do the lookup. 
         # We don't need to explicitly downcase integers or an id.
@@ -3093,6 +3104,18 @@ sub __Wipeout
     return;
 }
 
+our %CASE_INSENSITIVE_FIELDS;
+sub _CaseInsensitiveFields {
+    my $self = shift;
+    if ( !$CASE_INSENSITIVE_FIELDS{ ref $self } ) {
+        if ( my $meta = $self->_ClassAccessible ) {
+            $CASE_INSENSITIVE_FIELDS{ ref $self }
+                = { map { $_ => 1 } grep { not ( $meta->{$_}{is_case_sensitive} // 1 ) } keys %$meta };
+        }
+    }
+    return $CASE_INSENSITIVE_FIELDS{ ref $self };
+}
+
 RT::Base->_ImportOverlays();
 
 1;

commit 2a9804dc9591a8f80578a51702050f793e09e453
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Tue Mar 28 04:33:01 2023 +0800

    Limit to user defined groups on REST 1.0 search
    
    This limitation was missed by accident.

diff --git a/share/html/REST/1.0/Forms/group/ns b/share/html/REST/1.0/Forms/group/ns
index 305ecde84c..b25a1684da 100644
--- a/share/html/REST/1.0/Forms/group/ns
+++ b/share/html/REST/1.0/Forms/group/ns
@@ -54,6 +54,7 @@ $id
 use RT::Groups;
 
 my $groups = RT::Groups->new($session{CurrentUser});
+$groups->LimitToUserDefinedGroups;
 $groups->Limit(FIELD => 'Name', OPERATOR => '=', VALUE => $id, CASESENSITIVE => 0);
 if ($groups->Count == 0) {
     return (0, "No group named $id exists.");

commit 8fa425fbb90ac821e4883379c84436c9bb44b423
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Tue Mar 28 04:03:13 2023 +0800

    Make Groups.Name searches case sensitively by default
    
    Only user defined groups are case insensitive and should be searched in
    that way. Because of this, we need to create 2 indexes, to support both
    sensitive and insensitive searches.

diff --git a/etc/initialdata b/etc/initialdata
index fd92695b58..4a4f991b2f 100644
--- a/etc/initialdata
+++ b/etc/initialdata
@@ -856,7 +856,7 @@ Hour:         { $SubscriptionObj->SubValue('Hour') }
       Right  => 'SuperUser', },
 
     { GroupDomain => 'SystemInternal',
-      GroupType => 'privileged',
+      GroupType => 'Privileged',
       Right  => 'ShowApprovalsTab', },
 
     {   GroupDomain => 'SystemInternal',
diff --git a/etc/schema.Oracle b/etc/schema.Oracle
index 25fb737e40..c60e88705a 100644
--- a/etc/schema.Oracle
+++ b/etc/schema.Oracle
@@ -84,8 +84,10 @@ CREATE TABLE Groups (
         LastUpdated     DATE
 --      Instance        VARCHAR2(64)
 );
-CREATE INDEX Groups1 ON Groups (Domain, LOWER(Name), Instance);
+CREATE INDEX Groups1 ON Groups (Domain, Name, Instance);
 CREATE INDEX Groups2 ON Groups (Instance);
+-- Oracle's partial index is bound to partitions, kinda inconvenient to use here.
+CREATE INDEX Groups3 ON Groups (Domain, LOWER(Name));
 
 
 CREATE SEQUENCE SCRIPCONDITIONS_seq;
diff --git a/etc/schema.Pg b/etc/schema.Pg
index c3d36064fb..4aeb71a80e 100644
--- a/etc/schema.Pg
+++ b/etc/schema.Pg
@@ -140,8 +140,10 @@ CREATE TABLE Groups (
   PRIMARY KEY (id)
 
 );
-CREATE INDEX Groups1 ON Groups (Domain, LOWER(Name), Instance);
+CREATE INDEX Groups1 ON Groups (Domain, Name, Instance);
 CREATE INDEX Groups2 On Groups (Instance);
+-- Only user defined groups are case insensitive
+CREATE INDEX Groups3 ON Groups (Domain, LOWER(Name)) WHERE Domain = 'UserDefined';
 
 
 
diff --git a/etc/upgrade/5.0.4/schema.Oracle b/etc/upgrade/5.0.4/schema.Oracle
index c4d521d7f1..e6d78cafaf 100644
--- a/etc/upgrade/5.0.4/schema.Oracle
+++ b/etc/upgrade/5.0.4/schema.Oracle
@@ -9,4 +9,5 @@ CREATE INDEX Attachments4 ON Attachments (LOWER(Filename));
 DROP INDEX ObjectCustomFieldValues1;
 CREATE INDEX ObjectCustomFieldValues1 ON ObjectCustomFieldValues (LOWER(Content));
 DROP INDEX Groups1;
-CREATE INDEX Groups1 ON Groups (Domain, LOWER(Name), Instance);
+CREATE INDEX Groups1 ON Groups (Domain, Name, Instance);
+CREATE INDEX Groups3 ON Groups (Domain, LOWER(Name));
diff --git a/etc/upgrade/5.0.4/schema.Pg b/etc/upgrade/5.0.4/schema.Pg
index 188bf8ba1c..acbcd86b26 100644
--- a/etc/upgrade/5.0.4/schema.Pg
+++ b/etc/upgrade/5.0.4/schema.Pg
@@ -9,4 +9,5 @@ CREATE INDEX Attachments4 ON Attachments (LOWER(Filename));
 DROP INDEX ObjectCustomFieldValues1;
 CREATE INDEX ObjectCustomFieldValues1 ON ObjectCustomFieldValues (CustomField, ObjectType, ObjectId, LOWER(Content));
 DROP INDEX Groups1;
-CREATE INDEX Groups1 ON Groups (Domain, LOWER(Name), Instance);
+CREATE INDEX Groups1 ON Groups (Domain, Name, Instance);
+CREATE INDEX Groups3 ON Groups (Domain, LOWER(Name)) WHERE Domain = 'UserDefined';
diff --git a/lib/RT/CustomRole.pm b/lib/RT/CustomRole.pm
index 4c7dbed980..1a832bf30c 100644
--- a/lib/RT/CustomRole.pm
+++ b/lib/RT/CustomRole.pm
@@ -728,7 +728,7 @@ sub _SetGroupsDisabledForObject {
         }
 
         $groups->Limit(FIELD => 'Domain', OPERATOR => 'LIKE', VALUE => $subgroup_config->{Domain});
-        $groups->Limit(FIELD => 'Name', OPERATOR => '=', VALUE => $self->GroupType, CASESENSITIVE => 0);
+        $groups->Limit(FIELD => 'Name', OPERATOR => '=', VALUE => $self->GroupType);
 
         my $objects = $groups->Join(
             ALIAS1 => 'main',
diff --git a/lib/RT/Group.pm b/lib/RT/Group.pm
index 8cf69a6436..5562e771b3 100644
--- a/lib/RT/Group.pm
+++ b/lib/RT/Group.pm
@@ -1526,7 +1526,7 @@ sub _CoreAccessible {
         id =>
                 {read => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => ''},
         Name =>
-                {read => 1, write => 1, sql_type => 12, length => 200,  is_blob => 0,  is_numeric => 0,  type => 'varchar(200)', default => '', is_case_sensitive => 0},
+                {read => 1, write => 1, sql_type => 12, length => 200,  is_blob => 0,  is_numeric => 0,  type => 'varchar(200)', default => ''},
         Description =>
                 {read => 1, write => 1, sql_type => 12, length => 255,  is_blob => 0,  is_numeric => 0,  type => 'varchar(255)', default => '', is_case_sensitive => 0},
         Domain =>
diff --git a/lib/RT/Interface/Web.pm b/lib/RT/Interface/Web.pm
index 1fb7638d87..2ac8c28aa0 100644
--- a/lib/RT/Interface/Web.pm
+++ b/lib/RT/Interface/Web.pm
@@ -4298,7 +4298,7 @@ sub GetPrincipalsMap {
                 FIELD2 => 'id',
             );
             $Users->Limit( ALIAS => $groups, FIELD => 'Domain', VALUE => 'ACLEquivalence' );
-            $Users->Limit( ALIAS => $groups, FIELD => 'Name', VALUE => 'UserEquiv', CASESENSITIVE => 0 );
+            $Users->Limit( ALIAS => $groups, FIELD => 'Name', VALUE => 'UserEquiv' );
 
             push @map, [
                 'Users' => $Users,  # loc_left_pair
diff --git a/lib/RT/Principal.pm b/lib/RT/Principal.pm
index f01357a6d4..254eaf72d2 100644
--- a/lib/RT/Principal.pm
+++ b/lib/RT/Principal.pm
@@ -640,10 +640,10 @@ sub _HasRoleRightQuery {
     if ( $args{'Roles'} ) {
         $query .= "AND ("
             . join( ' OR ',
-                ( $RT::Handle->__MakeClauseCaseInsensitive( 'Groups.Name', '=', '?' ) )
+                ( 'Groups.Name = ?' )
                 x @{ $args{'Roles'} } )
             . ")";
-        push @bind_values, map { lc $_ } @{ $args{'Roles'} };
+        push @bind_values, @{ $args{'Roles'} };
     }
 
     my @object_clauses;
diff --git a/lib/RT/SearchBuilder/Role/Roles.pm b/lib/RT/SearchBuilder/Role/Roles.pm
index 699c0d25d8..171f6e0f0e 100644
--- a/lib/RT/SearchBuilder/Role/Roles.pm
+++ b/lib/RT/SearchBuilder/Role/Roles.pm
@@ -136,7 +136,6 @@ sub _RoleGroupsJoin {
         ALIAS           => $groups,
         FIELD           => 'Name',
         VALUE           => $name,
-        CASESENSITIVE   => 0,
     ) if $name;
 
     $self->{'_sql_role_group_aliases'}{ $args{'Class'} .'-'. $name } = $groups
diff --git a/lib/RT/Tickets.pm b/lib/RT/Tickets.pm
index c8b40af265..39f25d4781 100644
--- a/lib/RT/Tickets.pm
+++ b/lib/RT/Tickets.pm
@@ -2881,7 +2881,6 @@ sub CurrentUserCanSee {
                     FIELD           => 'Name',
                     VALUE           => $role,
                     ENTRYAGGREGATOR => 'AND',
-                    CASESENSITIVE   => 0,
                 );
             }
             $limit_queues->( 'AND', @$queues ) if ref $queues;
diff --git a/lib/RT/Users.pm b/lib/RT/Users.pm
index a54414134b..7794dfd057 100644
--- a/lib/RT/Users.pm
+++ b/lib/RT/Users.pm
@@ -483,7 +483,7 @@ sub WhoHaveRoleRight
                 );
 
     $self->_AddSubClause( "WhichRole", "(". join( ' OR ',
-        map $RT::Handle->__MakeClauseCaseInsensitive("$groups.Name", '=', "'$_'"), @roles
+        map "$groups.Name = '$_'", @roles
     ) .")" );
 
     my @groups_clauses = $self->_RoleClauses( $groups, @objects );

commit 36f07932ac51fdda6b51856bdc846347c953c4e9
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Tue Mar 28 03:22:14 2023 +0800

    Make Groups.Domain searches case sensitively by default
    
    Domain values are pre-defined and do not have user inputs.

diff --git a/etc/schema.Oracle b/etc/schema.Oracle
index 1c2e205305..25fb737e40 100644
--- a/etc/schema.Oracle
+++ b/etc/schema.Oracle
@@ -84,7 +84,7 @@ CREATE TABLE Groups (
         LastUpdated     DATE
 --      Instance        VARCHAR2(64)
 );
-CREATE INDEX Groups1 ON Groups (LOWER(Domain), LOWER(Name), Instance);
+CREATE INDEX Groups1 ON Groups (Domain, LOWER(Name), Instance);
 CREATE INDEX Groups2 ON Groups (Instance);
 
 
diff --git a/etc/schema.Pg b/etc/schema.Pg
index ba470daeb6..c3d36064fb 100644
--- a/etc/schema.Pg
+++ b/etc/schema.Pg
@@ -140,7 +140,7 @@ CREATE TABLE Groups (
   PRIMARY KEY (id)
 
 );
-CREATE INDEX Groups1 ON Groups (LOWER(Domain), LOWER(Name), Instance);
+CREATE INDEX Groups1 ON Groups (Domain, LOWER(Name), Instance);
 CREATE INDEX Groups2 On Groups (Instance);
 
 
diff --git a/etc/upgrade/5.0.4/schema.Oracle b/etc/upgrade/5.0.4/schema.Oracle
index 67c43908b3..c4d521d7f1 100644
--- a/etc/upgrade/5.0.4/schema.Oracle
+++ b/etc/upgrade/5.0.4/schema.Oracle
@@ -8,3 +8,5 @@ DROP INDEX Attachments4;
 CREATE INDEX Attachments4 ON Attachments (LOWER(Filename));
 DROP INDEX ObjectCustomFieldValues1;
 CREATE INDEX ObjectCustomFieldValues1 ON ObjectCustomFieldValues (LOWER(Content));
+DROP INDEX Groups1;
+CREATE INDEX Groups1 ON Groups (Domain, LOWER(Name), Instance);
diff --git a/etc/upgrade/5.0.4/schema.Pg b/etc/upgrade/5.0.4/schema.Pg
index 196e86bb44..188bf8ba1c 100644
--- a/etc/upgrade/5.0.4/schema.Pg
+++ b/etc/upgrade/5.0.4/schema.Pg
@@ -8,3 +8,5 @@ DROP INDEX Attachments4;
 CREATE INDEX Attachments4 ON Attachments (LOWER(Filename));
 DROP INDEX ObjectCustomFieldValues1;
 CREATE INDEX ObjectCustomFieldValues1 ON ObjectCustomFieldValues (CustomField, ObjectType, ObjectId, LOWER(Content));
+DROP INDEX Groups1;
+CREATE INDEX Groups1 ON Groups (Domain, LOWER(Name), Instance);
diff --git a/lib/RT/Asset.pm b/lib/RT/Asset.pm
index 822ed46ab6..e03db722d7 100644
--- a/lib/RT/Asset.pm
+++ b/lib/RT/Asset.pm
@@ -718,7 +718,7 @@ sub FindDependencies {
 
     # Asset role groups( Owner, HeldBy, Contact )
     my $objs = RT::Groups->new( $self->CurrentUser );
-    $objs->Limit( FIELD => 'Domain', VALUE => 'RT::Asset-Role', CASESENSITIVE => 0 );
+    $objs->Limit( FIELD => 'Domain', VALUE => 'RT::Asset-Role' );
     $objs->Limit( FIELD => 'Instance', VALUE => $self->Id );
     $deps->Add( in => $objs );
 
diff --git a/lib/RT/Catalog.pm b/lib/RT/Catalog.pm
index a1fa186708..c90f1c97a5 100644
--- a/lib/RT/Catalog.pm
+++ b/lib/RT/Catalog.pm
@@ -507,7 +507,7 @@ sub FindDependencies {
 
     # Role groups( HeldBy, Contact)
     my $objs = RT::Groups->new( $self->CurrentUser );
-    $objs->Limit( FIELD => 'Domain', VALUE => 'RT::Catalog-Role', CASESENSITIVE => 0 );
+    $objs->Limit( FIELD => 'Domain', VALUE => 'RT::Catalog-Role' );
     $objs->Limit( FIELD => 'Instance', VALUE => $self->Id );
     $deps->Add( in => $objs );
 
diff --git a/lib/RT/CustomRole.pm b/lib/RT/CustomRole.pm
index a39e7b8a52..4c7dbed980 100644
--- a/lib/RT/CustomRole.pm
+++ b/lib/RT/CustomRole.pm
@@ -727,7 +727,7 @@ sub _SetGroupsDisabledForObject {
             $groups->LimitToDeleted;
         }
 
-        $groups->Limit(FIELD => 'Domain', OPERATOR => 'LIKE', VALUE => $subgroup_config->{Domain}, CASESENSITIVE => 0 );
+        $groups->Limit(FIELD => 'Domain', OPERATOR => 'LIKE', VALUE => $subgroup_config->{Domain});
         $groups->Limit(FIELD => 'Name', OPERATOR => '=', VALUE => $self->GroupType, CASESENSITIVE => 0);
 
         my $objects = $groups->Join(
diff --git a/lib/RT/Group.pm b/lib/RT/Group.pm
index 33c47aaea7..8cf69a6436 100644
--- a/lib/RT/Group.pm
+++ b/lib/RT/Group.pm
@@ -1530,7 +1530,7 @@ sub _CoreAccessible {
         Description =>
                 {read => 1, write => 1, sql_type => 12, length => 255,  is_blob => 0,  is_numeric => 0,  type => 'varchar(255)', default => '', is_case_sensitive => 0},
         Domain =>
-                {read => 1, write => 1, sql_type => 12, length => 64,  is_blob => 0,  is_numeric => 0,  type => 'varchar(64)', default => '', is_case_sensitive => 0},
+                {read => 1, write => 1, sql_type => 12, length => 64,  is_blob => 0,  is_numeric => 0,  type => 'varchar(64)', default => ''},
         Instance =>
                 {read => 1, write => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => ''},
         Creator =>
diff --git a/lib/RT/Groups.pm b/lib/RT/Groups.pm
index 2dd03bf56c..edcadf7777 100644
--- a/lib/RT/Groups.pm
+++ b/lib/RT/Groups.pm
@@ -141,7 +141,7 @@ Return only SystemInternal Groups, such as "privileged" "unprivileged" and "ever
 
 sub LimitToSystemInternalGroups {
     my $self = shift;
-    $self->Limit(FIELD => 'Domain', OPERATOR => '=', VALUE => 'SystemInternal', CASESENSITIVE => 0 );
+    $self->Limit(FIELD => 'Domain', OPERATOR => '=', VALUE => 'SystemInternal');
     # All system internal groups have the same instance. No reason to limit down further
     #$self->Limit(FIELD => 'Instance', OPERATOR => '=', VALUE => '0');
 }
@@ -158,7 +158,7 @@ Return only UserDefined Groups
 
 sub LimitToUserDefinedGroups {
     my $self = shift;
-    $self->Limit(FIELD => 'Domain', OPERATOR => '=', VALUE => 'UserDefined', CASESENSITIVE => 0 );
+    $self->Limit(FIELD => 'Domain', OPERATOR => '=', VALUE => 'UserDefined');
     # All user-defined groups have the same instance. No reason to limit down further
     #$self->Limit(FIELD => 'Instance', OPERATOR => '=', VALUE => '');
 }
@@ -178,7 +178,7 @@ L</LimitToRolesForSystem>.
 sub LimitToRolesForObject {
     my $self   = shift;
     my $object = shift;
-    $self->Limit(FIELD => 'Domain',   OPERATOR => '=', VALUE => ref($object) . "-Role", CASESENSITIVE => 0 );
+    $self->Limit(FIELD => 'Domain',   OPERATOR => '=', VALUE => ref($object) . "-Role");
     $self->Limit(FIELD => 'Instance', OPERATOR => '=', VALUE => $object->id);
 }
 
diff --git a/lib/RT/Interface/Web.pm b/lib/RT/Interface/Web.pm
index 1b02ba5da6..1fb7638d87 100644
--- a/lib/RT/Interface/Web.pm
+++ b/lib/RT/Interface/Web.pm
@@ -4297,7 +4297,7 @@ sub GetPrincipalsMap {
                 TABLE2 => 'Groups',
                 FIELD2 => 'id',
             );
-            $Users->Limit( ALIAS => $groups, FIELD => 'Domain', VALUE => 'ACLEquivalence', CASESENSITIVE => 0 );
+            $Users->Limit( ALIAS => $groups, FIELD => 'Domain', VALUE => 'ACLEquivalence' );
             $Users->Limit( ALIAS => $groups, FIELD => 'Name', VALUE => 'UserEquiv', CASESENSITIVE => 0 );
 
             push @map, [
diff --git a/lib/RT/Principal.pm b/lib/RT/Principal.pm
index b36a6c4191..f01357a6d4 100644
--- a/lib/RT/Principal.pm
+++ b/lib/RT/Principal.pm
@@ -650,8 +650,8 @@ sub _HasRoleRightQuery {
     foreach my $obj ( @{ $args{'EquivObjects'} } ) {
         my $type = ref($obj) ? ref($obj) : $obj;
 
-        my $role_clause = $RT::Handle->__MakeClauseCaseInsensitive( "Groups.Domain", '=', '?' );
-        push @bind_values, lc "$type-Role";
+        my $role_clause = "Groups.Domain = ?";
+        push @bind_values, "$type-Role";
         if ( my $id = eval { $obj->id } ) {
             $role_clause .= " AND Groups.Instance = ?";
             push @bind_values, $id;
diff --git a/lib/RT/Queue.pm b/lib/RT/Queue.pm
index 7e2c8ecd4a..56fcd3f845 100644
--- a/lib/RT/Queue.pm
+++ b/lib/RT/Queue.pm
@@ -1032,7 +1032,7 @@ sub FindDependencies {
 
     # Queue role groups( Cc, AdminCc )
     my $objs = RT::Groups->new( $self->CurrentUser );
-    $objs->Limit( FIELD => 'Domain', VALUE => 'RT::Queue-Role', CASESENSITIVE => 0 );
+    $objs->Limit( FIELD => 'Domain', VALUE => 'RT::Queue-Role' );
     $objs->Limit( FIELD => 'Instance', VALUE => $self->Id );
     $deps->Add( in => $objs );
 
@@ -1109,7 +1109,7 @@ sub __DependsOn {
 
 # Queue role groups( Cc, AdminCc )
     $objs = RT::Groups->new( $self->CurrentUser );
-    $objs->Limit( FIELD => 'Domain', VALUE => 'RT::Queue-Role', CASESENSITIVE => 0 );
+    $objs->Limit( FIELD => 'Domain', VALUE => 'RT::Queue-Role' );
     $objs->Limit( FIELD => 'Instance', VALUE => $self->Id );
     push( @$list, $objs );
 
diff --git a/lib/RT/SearchBuilder/Role/Roles.pm b/lib/RT/SearchBuilder/Role/Roles.pm
index 4f80302a8d..699c0d25d8 100644
--- a/lib/RT/SearchBuilder/Role/Roles.pm
+++ b/lib/RT/SearchBuilder/Role/Roles.pm
@@ -130,7 +130,6 @@ sub _RoleGroupsJoin {
         ALIAS           => $groups,
         FIELD           => 'Domain',
         VALUE           => $args{'Class'} .'-Role',
-        CASESENSITIVE   => 0,
     );
     $self->Limit(
         LEFTJOIN        => $groups,
diff --git a/lib/RT/Test.pm b/lib/RT/Test.pm
index 7972b06b18..084bd795d0 100644
--- a/lib/RT/Test.pm
+++ b/lib/RT/Test.pm
@@ -767,7 +767,6 @@ sub load_or_create_user {
         );
         $gms->Limit(
             ALIAS => $groups_alias, FIELD => 'Domain', VALUE => 'UserDefined',
-            CASESENSITIVE => 0,
         );
         $gms->Limit( FIELD => 'MemberId', VALUE => $obj->id );
         while ( my $group_member_record = $gms->Next ) {
diff --git a/lib/RT/Ticket.pm b/lib/RT/Ticket.pm
index 1a84820fb5..d8e65f2b21 100644
--- a/lib/RT/Ticket.pm
+++ b/lib/RT/Ticket.pm
@@ -3734,7 +3734,7 @@ sub FindDependencies {
 
     # Ticket role groups( Owner, Requestors, Cc, AdminCc )
     $objs = RT::Groups->new( $self->CurrentUser );
-    $objs->Limit( FIELD => 'Domain', VALUE => 'RT::Ticket-Role', CASESENSITIVE => 0 );
+    $objs->Limit( FIELD => 'Domain', VALUE => 'RT::Ticket-Role' );
     $objs->Limit( FIELD => 'Instance', VALUE => $self->Id );
     $deps->Add( in => $objs );
 
@@ -3764,7 +3764,7 @@ sub __DependsOn {
 
 # Ticket role groups( Owner, Requestors, Cc, AdminCc )
     $objs = RT::Groups->new( $self->CurrentUser );
-    $objs->Limit( FIELD => 'Domain', VALUE => 'RT::Ticket-Role', CASESENSITIVE => 0 );
+    $objs->Limit( FIELD => 'Domain', VALUE => 'RT::Ticket-Role' );
     $objs->Limit( FIELD => 'Instance', VALUE => $self->Id );
     push( @$list, $objs );
 
diff --git a/lib/RT/Tickets.pm b/lib/RT/Tickets.pm
index c00bb70b18..c8b40af265 100644
--- a/lib/RT/Tickets.pm
+++ b/lib/RT/Tickets.pm
@@ -2780,7 +2780,7 @@ sub CurrentUserCanSee {
     if ( my @tmp = grep $_ ne 'Owner' && !ref $roles{ $_ }, keys %roles ) {
 
         my $groups = RT::Groups->new( RT->SystemUser );
-        $groups->Limit( FIELD => 'Domain', VALUE => 'RT::Queue-Role', CASESENSITIVE => 0 );
+        $groups->Limit( FIELD => 'Domain', VALUE => 'RT::Queue-Role' );
         $groups->Limit(
             FIELD         => 'Name',
             OPERATOR      => 'IN',
diff --git a/lib/RT/User.pm b/lib/RT/User.pm
index b34565dc40..d1259c1454 100644
--- a/lib/RT/User.pm
+++ b/lib/RT/User.pm
@@ -1798,7 +1798,6 @@ sub WatchedQueues {
                             FIELD => 'Domain',
                             VALUE => 'RT::Queue-Role',
                             ENTRYAGGREGATOR => 'AND',
-                            CASESENSITIVE => 0,
                           );
     if (grep { $_ eq 'Cc' } @roles) {
         $watched_queues->Limit(
@@ -2936,7 +2935,7 @@ sub FindDependencies {
 
     # ACL equivalence group
     my $objs = RT::Groups->new( $self->CurrentUser );
-    $objs->Limit( FIELD => 'Domain', VALUE => 'ACLEquivalence', CASESENSITIVE => 0 );
+    $objs->Limit( FIELD => 'Domain', VALUE => 'ACLEquivalence' );
     $objs->Limit( FIELD => 'Instance', VALUE => $self->Id );
     $deps->Add( in => $objs );
 
@@ -2953,7 +2952,6 @@ sub FindDependencies {
         ALIAS => $groups,
         FIELD => 'Domain',
         VALUE => 'SystemInternal',
-        CASESENSITIVE => 0
     );
     $deps->Add( in => $objs );
 
@@ -2982,7 +2980,7 @@ sub __DependsOn {
 # ACL equivalence group
 # don't use LoadACLEquivalenceGroup cause it may not exists any more
     my $objs = RT::Groups->new( $self->CurrentUser );
-    $objs->Limit( FIELD => 'Domain', VALUE => 'ACLEquivalence', CASESENSITIVE => 0 );
+    $objs->Limit( FIELD => 'Domain', VALUE => 'ACLEquivalence' );
     $objs->Limit( FIELD => 'Instance', VALUE => $self->Id );
     push( @$list, $objs );
 
diff --git a/lib/RT/Users.pm b/lib/RT/Users.pm
index 33c7bbf7d0..a54414134b 100644
--- a/lib/RT/Users.pm
+++ b/lib/RT/Users.pm
@@ -502,7 +502,7 @@ sub _RoleClauses {
     foreach my $obj ( @objects ) {
         my $type = ref($obj)? ref($obj): $obj;
 
-        my $role_clause = $RT::Handle->__MakeClauseCaseInsensitive("$groups.Domain", '=', "'$type-Role'");
+        my $role_clause = "$groups.Domain = '$type-Role'";
 
         if ( my $id = eval { $obj->id } ) {
             $role_clause .= " AND $groups.Instance = $id";
diff --git a/share/html/Admin/Elements/SelectGroups b/share/html/Admin/Elements/SelectGroups
index c44b6a795e..0b0cb8ab6c 100644
--- a/share/html/Admin/Elements/SelectGroups
+++ b/share/html/Admin/Elements/SelectGroups
@@ -53,7 +53,7 @@
 
 <%INIT>
 my $groups = RT::Groups->new($session{'CurrentUser'});
-$groups->Limit(FIELD => 'Domain', OPERATOR => '=', VALUE => $Domain, CASESENSITIVE => 0 );
+$groups->Limit(FIELD => 'Domain', OPERATOR => '=', VALUE => $Domain);
 
 </%INIT>
 <%ARGS>
diff --git a/share/html/Elements/ShowMemberships b/share/html/Elements/ShowMemberships
index 905cc1c555..23dd62d4bf 100644
--- a/share/html/Elements/ShowMemberships
+++ b/share/html/Elements/ShowMemberships
@@ -71,14 +71,12 @@ $GroupMembers->Limit(
     FIELD      => 'Domain',
     OPERATOR   => '=',
     VALUE      => 'SystemInternal',
-    CASESENSITIVE => 0,
 );
 $GroupMembers->Limit(
     ALIAS      => $alias,
     FIELD      => 'Domain',
     OPERATOR   => '=',
     VALUE      => 'UserDefined',
-    CASESENSITIVE => 0,
 );
 $GroupMembers->OrderByCols(
     { ALIAS => $alias, FIELD => 'Domain' },
diff --git a/share/html/Search/Elements/SelectGroup b/share/html/Search/Elements/SelectGroup
index eeb8ca2319..0636fa862a 100644
--- a/share/html/Search/Elements/SelectGroup
+++ b/share/html/Search/Elements/SelectGroup
@@ -56,7 +56,7 @@
 
 <%INIT>
 my $groups = RT::Groups->new($session{'CurrentUser'});
-$groups->Limit(FIELD => 'Domain', OPERATOR => '=', VALUE => $Domain, CASESENSITIVE => 0);
+$groups->Limit(FIELD => 'Domain', OPERATOR => '=', VALUE => $Domain);
 
 </%INIT>
 <%ARGS>

commit 98b4d18621127004306361c38ae4e8f51cf99ee6
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Sat Oct 1 00:27:26 2022 +0800

    Update SQL tests as Status and Lifecycle are searched case insensitively now

diff --git a/t/api/sql.t b/t/api/sql.t
index 262a6c2d8b..943e234d53 100644
--- a/t/api/sql.t
+++ b/t/api/sql.t
@@ -28,6 +28,19 @@ RT->Config->Set(
         defaults => { on_create => 'new', },
     },
 );
+my $status_key = RT->DatabaseHandle->CaseSensitive ? 'LOWER\(\w+.Status\)' : 'Status';
+my $lifecycle_key = RT->DatabaseHandle->CaseSensitive ? 'LOWER\(\w+.Lifecycle\)' : 'Lifecycle';
+
+my %ticketsql = (
+    q{Status = 'new' OR Status = 'open'}                => qr{$status_key IN \('new', 'open'\)},
+    q{Status = '__Active__'}                            => qr{$status_key IN \('new', 'open', 'stalled'\)},
+    q{id = 2 OR id = 3}                                 => qr{id IN \('2', '3'\)},
+    q{Creator = 'root' OR Creator = 'alice'}            => qr{Creator IN \('$alice_id', '$root_id'\)},
+    q{Queue = 'General' OR Queue = 'Support'}           => qr{Queue IN \('$general_id', '$support_id'\)},
+    q{Lifecycle = 'default' or Lifecycle = 'approvals'} => qr{$lifecycle_key IN \('approvals', 'default'\)},
+    q{(Queue = 'General' OR Queue = 'Support') AND (Status = 'new' OR Status = 'open')} =>
+        qr{Queue IN \('$general_id', '$support_id'\).+$status_key IN \('new', 'open'\)},
+);
 
 RT::Lifecycle->FillCache();
 
@@ -38,14 +51,14 @@ my $hardware_catalog_id = RT::Test::Assets->load_or_create_catalog( Name => 'Har
 my %sql = (
     'RT::Tickets' => {
         like => {
-            q{Status = 'new' OR Status = 'open'}                => qr{Status IN \('new', 'open'\)},
-            q{Status = '__Active__'}                            => qr{Status IN \('new', 'open', 'stalled'\)},
+            q{Status = 'new' OR Status = 'open'}                => qr{$status_key IN \('new', 'open'\)},
+            q{Status = '__Active__'}                            => qr{$status_key IN \('new', 'open', 'stalled'\)},
             q{id = 2 OR id = 3}                                 => qr{id IN \('2', '3'\)},
             q{Creator = 'root' OR Creator = 'alice'}            => qr{Creator IN \('$alice_id', '$root_id'\)},
             q{Queue = 'General' OR Queue = 'Support'}           => qr{Queue IN \('$general_id', '$support_id'\)},
-            q{Lifecycle = 'default' or Lifecycle = 'approvals'} => qr{Lifecycle IN \('approvals', 'default'\)},
+            q{Lifecycle = 'default' or Lifecycle = 'approvals'} => qr{$lifecycle_key IN \('approvals', 'default'\)},
             q{(Queue = 'General' OR Queue = 'Support') AND (Status = 'new' OR Status = 'open')} =>
-                qr{Queue IN \('$general_id', '$support_id'\).+Status IN \('new', 'open'\)},
+                qr{Queue IN \('$general_id', '$support_id'\).+$status_key IN \('new', 'open'\)},
         },
         unlike => {
             q{Status = '__Active__' and Queue = 'General'}       => qr{approvals},
@@ -54,17 +67,17 @@ my %sql = (
     },
     'RT::Transactions' => {
         like => {
-            q{TicketStatus = 'new' OR TicketStatus = 'open'}      => qr{Status IN \('new', 'open'\)},
-            q{TicketStatus = '__Active__'}                        => qr{Status IN \('new', 'open', 'stalled'\)},
+            q{TicketStatus = 'new' OR TicketStatus = 'open'}      => qr{$status_key IN \('new', 'open'\)},
+            q{TicketStatus = '__Active__'}                        => qr{$status_key IN \('new', 'open', 'stalled'\)},
             q{id = 2 OR id = 3}                                   => qr{id IN \('2', '3'\)},
             q{Creator = 'root' OR Creator = 'alice'}              => qr{Creator IN \('$alice_id', '$root_id'\)},
             q{TicketCreator = 'root' OR TicketCreator = 'alice'}  => qr{Creator IN \('$alice_id', '$root_id'\)},
             q{TicketLastUpdatedBy = 'root' OR TicketLastUpdatedBy = 'alice'}  => qr{LastUpdatedBy IN \('$alice_id', '$root_id'\)},
             q{TicketQueue = 'General' OR TicketQueue = 'Support'} => qr{Queue IN \('$general_id', '$support_id'\)},
             q{TicketQueueLifecycle = 'default' or TicketQueueLifecycle = 'approvals'} =>
-                qr{Lifecycle IN \('approvals', 'default'\)},
+                qr{$lifecycle_key IN \('approvals', 'default'\)},
             q{(TicketQueue = 'General' OR TicketQueue = 'Support') AND (TicketStatus = 'new' OR TicketStatus = 'open')}
-                => qr{Queue IN \('$general_id', '$support_id'\).+Status IN \('new', 'open'\)},
+                => qr{Queue IN \('$general_id', '$support_id'\).+$status_key IN \('new', 'open'\)},
         },
         unlike => {
             q{TicketStatus = '__Active__' and TicketQueue = 'General'} => qr{approvals},
@@ -72,13 +85,13 @@ my %sql = (
     },
     'RT::Assets' => {
         like => {
-            q{Status = 'new' OR Status = 'allocated'}             => qr{Status IN \('allocated', 'new'\)},
-            q{Status = '__Active__'}                              => qr{Status IN \('allocated', 'in-use', 'new'\)},
+            q{Status = 'new' OR Status = 'allocated'}             => qr{$status_key IN \('allocated', 'new'\)},
+            q{Status = '__Active__'}                              => qr{$status_key IN \('allocated', 'in-use', 'new'\)},
             q{id = 2 OR id = 3}                                   => qr{id IN \('2', '3'\)},
             q{Catalog = 'General assets' OR Catalog = 'Hardware'} =>
                 qr{Catalog IN \('$general_catalog_id', '$hardware_catalog_id'\)},
             q{(Catalog = 'General assets' OR Catalog = 'Hardware') AND (Status = 'allocated' OR Status = 'new')} =>
-                qr{Catalog IN \('$general_catalog_id', '$hardware_catalog_id'\).+Status IN \('allocated', 'new'\)},
+                qr{Catalog IN \('$general_catalog_id', '$hardware_catalog_id'\).+$status_key IN \('allocated', 'new'\)},
         },
         unlike => {
             q{Status = '__Active__' and Catalog = 'General assets'} => qr{hardware},

commit e81dbf7ec86274281bad07006af47a468cfd0384
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Thu Mar 23 15:53:55 2023 +0800

    Use is_case_sensitive to determine case sensitivity for FromSQL string limits
    
    The SQL for transaction searches is a bit different: Previous all string
    fields like Type, Field, etc. were searched case insensitively, which
    wasn't necessary. Now only OldValue, NewValue and Data are searched that
    way. SQL results should be the same.

diff --git a/lib/RT/Assets.pm b/lib/RT/Assets.pm
index bc9f942073..359cb7c8dc 100644
--- a/lib/RT/Assets.pm
+++ b/lib/RT/Assets.pm
@@ -1217,20 +1217,10 @@ sub _StringLimit {
         $value = 'NULL';
     }
 
-    if ($field eq "Status") {
-        if ( ref $value eq 'ARRAY' ) {
-            $value = [ map lc, @$value ];
-        }
-        else {
-            $value = lc $value;
-        }
-    }
-
     $sb->Limit(
         FIELD         => $field,
         OPERATOR      => $op,
         VALUE         => $value,
-        CASESENSITIVE => 0,
         @rest,
     );
 }
diff --git a/lib/RT/Tickets.pm b/lib/RT/Tickets.pm
index bf2540efcc..c00bb70b18 100644
--- a/lib/RT/Tickets.pm
+++ b/lib/RT/Tickets.pm
@@ -725,20 +725,10 @@ sub _StringLimit {
         $value = 'NULL';
     }
 
-    if ($field eq "Status") {
-        if ( ref $value eq 'ARRAY' ) {
-            $value = [ map lc, @$value ];
-        }
-        else {
-            $value = lc $value;
-        }
-    }
-
     $sb->Limit(
         FIELD         => $field,
         OPERATOR      => $op,
         VALUE         => $value,
-        CASESENSITIVE => 0,
         @rest,
     );
 }
@@ -906,7 +896,6 @@ sub _TransLimit {
         FIELD         => $field,
         OPERATOR      => $op,
         VALUE         => $value,
-        CASESENSITIVE => 0,
     );
 }
 
diff --git a/lib/RT/Transactions.pm b/lib/RT/Transactions.pm
index 0c33e6b135..fde5c9a7ef 100644
--- a/lib/RT/Transactions.pm
+++ b/lib/RT/Transactions.pm
@@ -456,7 +456,6 @@ sub _StringLimit {
         FIELD         => $field,
         OPERATOR      => $op,
         VALUE         => $value,
-        CASESENSITIVE => 0,
         @rest,
     );
 }
@@ -860,7 +859,6 @@ sub _TicketLimit {
         FIELD         => $field,
         OPERATOR      => $op,
         VALUE         => $value,
-        CASESENSITIVE => 0,
     );
 }
 

commit 85b54910d1f9cd5f5a1784aa6c668b744d14d05c
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Thu Mar 23 15:49:18 2023 +0800

    Mark more fields that contain user inputs case insensitive
    
    With this, we won't need to explicitly pass CASESENSITIVE => 0 to search
    them case insensitively.

diff --git a/lib/RT/Article.pm b/lib/RT/Article.pm
index 590b4fb989..43f6ba1696 100644
--- a/lib/RT/Article.pm
+++ b/lib/RT/Article.pm
@@ -836,9 +836,9 @@ sub _CoreAccessible {
         id =>
                 {read => 1, type => 'int(11)', default => ''},
         Name => 
-                {read => 1, write => 1, type => 'varchar(255)', default => ''},
+                {read => 1, write => 1, type => 'varchar(255)', default => '', is_case_sensitive => 0},
         Summary => 
-                {read => 1, write => 1, type => 'varchar(255)', default => ''},
+                {read => 1, write => 1, type => 'varchar(255)', default => '', is_case_sensitive => 0},
         SortOrder => 
                 {read => 1, write => 1, type => 'int(11)', default => '0', is_numeric => 1},
         Class => 
diff --git a/lib/RT/Asset.pm b/lib/RT/Asset.pm
index 68bb48fb74..822ed46ab6 100644
--- a/lib/RT/Asset.pm
+++ b/lib/RT/Asset.pm
@@ -691,7 +691,7 @@ sub _CoreAccessible {
         id            => { read => 1, type => 'int(11)',        default => '' },
         Name          => { read => 1, type => 'varchar(255)',   default => '',  write => 1, is_case_sensitive => 0 },
         Status        => { read => 1, type => 'varchar(64)',    default => '',  write => 1, is_case_sensitive => 0 },
-        Description   => { read => 1, type => 'varchar(255)',   default => '',  write => 1 },
+        Description   => { read => 1, type => 'varchar(255)',   default => '',  write => 1, is_case_sensitive => 0 },
         Catalog       => { read => 1, type => 'int(11)',        default => '0', write => 1 },
         Creator       => { read => 1, type => 'int(11)',        default => '0', auto => 1 },
         Created       => { read => 1, type => 'datetime',       default => '',  auto => 1 },
diff --git a/lib/RT/Attachment.pm b/lib/RT/Attachment.pm
index 5254c2c407..5767247f6c 100644
--- a/lib/RT/Attachment.pm
+++ b/lib/RT/Attachment.pm
@@ -1292,9 +1292,9 @@ sub _CoreAccessible {
         Parent =>
                 {read => 1, write => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(19)', default => '0'},
         MessageId =>
-                {read => 1, write => 1, sql_type => 12, length => 160,  is_blob => 0,  is_numeric => 0,  type => 'varchar(160)', default => ''},
+                {read => 1, write => 1, sql_type => 12, length => 160,  is_blob => 0,  is_numeric => 0,  type => 'varchar(160)', default => '', is_case_sensitive => 0},
         Subject =>
-                {read => 1, write => 1, sql_type => 12, length => 255,  is_blob => 0,  is_numeric => 0,  type => 'varchar(255)', default => ''},
+                {read => 1, write => 1, sql_type => 12, length => 255,  is_blob => 0,  is_numeric => 0,  type => 'varchar(255)', default => '', is_case_sensitive => 0},
         Filename =>
                 {read => 1, write => 1, sql_type => 12, length => 255,  is_blob => 0,  is_numeric => 0,  type => 'varchar(255)', default => '', is_case_sensitive => 0},
         ContentType =>
@@ -1304,7 +1304,7 @@ sub _CoreAccessible {
         Content =>
                 {read => 1, write => 1, sql_type => -4, length => 0,  is_blob => 1,  is_numeric => 0,  type => 'longblob', default => ''},
         Headers =>
-                {read => 1, write => 1, sql_type => -4, length => 0,  is_blob => 1,  is_numeric => 0,  type => 'longtext', default => ''},
+                {read => 1, write => 1, sql_type => -4, length => 0,  is_blob => 1,  is_numeric => 0,  type => 'longtext', default => '', is_case_sensitive => 0},
         Creator =>
                 {read => 1, auto => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => '0'},
         Created =>
diff --git a/lib/RT/Attribute.pm b/lib/RT/Attribute.pm
index d8d2db1434..b5a55de514 100644
--- a/lib/RT/Attribute.pm
+++ b/lib/RT/Attribute.pm
@@ -776,7 +776,7 @@ sub _CoreAccessible {
         Name =>
                 {read => 1, write => 1, sql_type => 12, length => 255,  is_blob => 0,  is_numeric => 0,  type => 'varchar(255)', default => ''},
         Description =>
-                {read => 1, write => 1, sql_type => 12, length => 255,  is_blob => 0,  is_numeric => 0,  type => 'varchar(255)', default => ''},
+                {read => 1, write => 1, sql_type => 12, length => 255,  is_blob => 0,  is_numeric => 0,  type => 'varchar(255)', default => '', is_case_sensitive => 0},
         Content =>
                 {read => 1, write => 1, sql_type => -4, length => 0,  is_blob => 1,  is_numeric => 0,  type => 'blob', default => ''},
         ContentType =>
diff --git a/lib/RT/Catalog.pm b/lib/RT/Catalog.pm
index 52b3102b1d..a1fa186708 100644
--- a/lib/RT/Catalog.pm
+++ b/lib/RT/Catalog.pm
@@ -489,8 +489,8 @@ sub _CoreAccessible {
     {
         id            => { read => 1, type => 'int(11)',        default => '' },
         Name          => { read => 1, type => 'varchar(255)',   default => '',          write => 1, is_case_sensitive => 0 },
-        Description   => { read => 1, type => 'varchar(255)',   default => '',          write => 1 },
-        Lifecycle     => { read => 1, type => 'varchar(32)',    default => 'assets',    write => 1 },
+        Description   => { read => 1, type => 'varchar(255)',   default => '',          write => 1, is_case_sensitive => 0 },
+        Lifecycle     => { read => 1, type => 'varchar(32)',    default => 'assets',    write => 1, is_case_sensitive => 0 },
         Disabled      => { read => 1, type => 'int(2)',         default => '0',         write => 1 },
         Creator       => { read => 1, type => 'int(11)',        default => '0', auto => 1 },
         Created       => { read => 1, type => 'datetime',       default => '',  auto => 1 },
diff --git a/lib/RT/Class.pm b/lib/RT/Class.pm
index 236d8548d9..a428261538 100644
--- a/lib/RT/Class.pm
+++ b/lib/RT/Class.pm
@@ -520,9 +520,9 @@ sub _CoreAccessible {
         id =>
                 {read => 1, type => 'int(11)', default => ''},
         Name => 
-                {read => 1, write => 1, type => 'varchar(255)', default => ''},
+                {read => 1, write => 1, type => 'varchar(255)', default => '', is_case_sensitive => 0},
         Description => 
-                {read => 1, write => 1, type => 'varchar(255)', default => ''},
+                {read => 1, write => 1, type => 'varchar(255)', default => '', is_case_sensitive => 0},
         SortOrder => 
                 {read => 1, write => 1, type => 'int(11)', default => '0'},
         Disabled => 
diff --git a/lib/RT/CurrentUser.pm b/lib/RT/CurrentUser.pm
index 271c88f6aa..c64f08d265 100644
--- a/lib/RT/CurrentUser.pm
+++ b/lib/RT/CurrentUser.pm
@@ -166,15 +166,14 @@ sub UserObj {
 }
 
 sub _CoreAccessible  {
-     {
-         Name           => { 'read' => 1 },
-           Gecos        => { 'read' => 1 },
-           RealName     => { 'read' => 1 },
-           Lang     => { 'read' => 1 },
-           Password     => { 'read' => 0, 'write' => 0 },
-          EmailAddress => { 'read' => 1, 'write' => 0 }
-     };
-  
+    {
+        Name         => { 'read' => 1, is_case_sensitive => 0 },
+        Gecos        => { 'read' => 1, is_case_sensitive => 0 },
+        RealName     => { 'read' => 1, is_case_sensitive => 0 },
+        Lang         => { 'read' => 1, is_case_sensitive => 0 },
+        Password     => { 'read' => 0, 'write'           => 0 },
+        EmailAddress => { 'read' => 1, 'write'           => 0, is_case_sensitive => 0 }
+    };
 }
 
 =head2 LoadByGecos
diff --git a/lib/RT/CustomField.pm b/lib/RT/CustomField.pm
index e81a83ee90..4c380cff47 100644
--- a/lib/RT/CustomField.pm
+++ b/lib/RT/CustomField.pm
@@ -2558,7 +2558,7 @@ sub _CoreAccessible {
         id =>
         {read => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => ''},
         Name => 
-        {read => 1, write => 1, sql_type => 12, length => 200,  is_blob => 0,  is_numeric => 0,  type => 'varchar(200)', default => ''},
+        {read => 1, write => 1, sql_type => 12, length => 200,  is_blob => 0,  is_numeric => 0,  type => 'varchar(200)', default => '', is_case_sensitive => 0},
         Type => 
         {read => 1, write => 1, sql_type => 12, length => 200,  is_blob => 0,  is_numeric => 0,  type => 'varchar(200)', default => ''},
         RenderType => 
@@ -2572,13 +2572,13 @@ sub _CoreAccessible {
         BasedOn => 
         {read => 1, write => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => ''},
         Description => 
-        {read => 1, write => 1, sql_type => 12, length => 255,  is_blob => 0,  is_numeric => 0,  type => 'varchar(255)', default => ''},
+        {read => 1, write => 1, sql_type => 12, length => 255,  is_blob => 0,  is_numeric => 0,  type => 'varchar(255)', default => '', is_case_sensitive => 0},
         SortOrder => 
         {read => 1, write => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => '0'},
         LookupType => 
         {read => 1, write => 1, sql_type => 12, length => 255,  is_blob => 0,  is_numeric => 0,  type => 'varchar(255)', default => ''},
         EntryHint =>
-        {read => 1, write => 1, sql_type => 12, length => 255,  is_blob => 0, is_numeric => 0,  type => 'varchar(255)', default => undef },
+        {read => 1, write => 1, sql_type => 12, length => 255,  is_blob => 0, is_numeric => 0,  type => 'varchar(255)', default => undef, is_case_sensitive => 0 },
         UniqueValues =>
         {read => 1, write => 1, sql_type => 5, length => 6,  is_blob => 0,  is_numeric => 1,  type => 'smallint(6)', default => '0'},
         CanonicalizeClass =>
diff --git a/lib/RT/CustomRole.pm b/lib/RT/CustomRole.pm
index cf22198491..a39e7b8a52 100644
--- a/lib/RT/CustomRole.pm
+++ b/lib/RT/CustomRole.pm
@@ -824,13 +824,13 @@ sub _CoreAccessible {
         id =>
         {read => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => ''},
         Name =>
-        {read => 1, write => 1, sql_type => 12, length => 200,  is_blob => 0,  is_numeric => 0,  type => 'varchar(200)', default => ''},
+        {read => 1, write => 1, sql_type => 12, length => 200,  is_blob => 0,  is_numeric => 0,  type => 'varchar(200)', default => '', is_case_sensitive => 0},
         Description =>
-        {read => 1, write => 1, sql_type => 12, length => 255,  is_blob => 0,  is_numeric => 0,  type => 'varchar(255)', default => ''},
+        {read => 1, write => 1, sql_type => 12, length => 255,  is_blob => 0,  is_numeric => 0,  type => 'varchar(255)', default => '', is_case_sensitive => 0},
         MaxValues =>
         {read => 1, write => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => ''},
         EntryHint =>
-        {read => 1, write => 1, sql_type => 12, length => 255,  is_blob => 0,  is_numeric => 0,  type => 'varchar(255)', default => ''},
+        {read => 1, write => 1, sql_type => 12, length => 255,  is_blob => 0,  is_numeric => 0,  type => 'varchar(255)', default => '', is_case_sensitive => 0},
         LookupType =>
         {read => 1, write => 1, sql_type => 12, length => 255,  is_blob => 0,  is_numeric => 0,  type => 'varchar(255)', default => ''},
         Creator =>
diff --git a/lib/RT/Group.pm b/lib/RT/Group.pm
index 28d2452d9c..33c47aaea7 100644
--- a/lib/RT/Group.pm
+++ b/lib/RT/Group.pm
@@ -1528,7 +1528,7 @@ sub _CoreAccessible {
         Name =>
                 {read => 1, write => 1, sql_type => 12, length => 200,  is_blob => 0,  is_numeric => 0,  type => 'varchar(200)', default => '', is_case_sensitive => 0},
         Description =>
-                {read => 1, write => 1, sql_type => 12, length => 255,  is_blob => 0,  is_numeric => 0,  type => 'varchar(255)', default => ''},
+                {read => 1, write => 1, sql_type => 12, length => 255,  is_blob => 0,  is_numeric => 0,  type => 'varchar(255)', default => '', is_case_sensitive => 0},
         Domain =>
                 {read => 1, write => 1, sql_type => 12, length => 64,  is_blob => 0,  is_numeric => 0,  type => 'varchar(64)', default => '', is_case_sensitive => 0},
         Instance =>
diff --git a/lib/RT/ObjectCustomFieldValue.pm b/lib/RT/ObjectCustomFieldValue.pm
index 1f8eba5680..074680a737 100644
--- a/lib/RT/ObjectCustomFieldValue.pm
+++ b/lib/RT/ObjectCustomFieldValue.pm
@@ -752,7 +752,7 @@ sub _CoreAccessible {
         Content =>
                 {read => 1, write => 1, sql_type => 12, length => 255,  is_blob => 0,  is_numeric => 0,  type => 'varchar(255)', default => '', is_case_sensitive => 0},
         LargeContent =>
-                {read => 1, write => 1, sql_type => -4, length => 0,  is_blob => 1,  is_numeric => 0,  type => 'longblob', default => ''},
+                {read => 1, write => 1, sql_type => -4, length => 0,  is_blob => 1,  is_numeric => 0,  type => 'longblob', default => '', is_case_sensitive => 0},
         ContentType =>
                 {read => 1, write => 1, sql_type => 12, length => 80,  is_blob => 0,  is_numeric => 0,  type => 'varchar(80)', default => ''},
         ContentEncoding =>
diff --git a/lib/RT/Queue.pm b/lib/RT/Queue.pm
index 08d45e89f4..7e2c8ecd4a 100644
--- a/lib/RT/Queue.pm
+++ b/lib/RT/Queue.pm
@@ -997,15 +997,15 @@ sub _CoreAccessible {
         Name => 
         {read => 1, write => 1, sql_type => 12, length => 200,  is_blob => 0,  is_numeric => 0,  type => 'varchar(200)', default => '', is_case_sensitive => 0 },
         Description => 
-        {read => 1, write => 1, sql_type => 12, length => 255,  is_blob => 0,  is_numeric => 0,  type => 'varchar(255)', default => ''},
+        {read => 1, write => 1, sql_type => 12, length => 255,  is_blob => 0,  is_numeric => 0,  type => 'varchar(255)', default => '', is_case_sensitive => 0},
         CorrespondAddress => 
-        {read => 1, write => 1, sql_type => 12, length => 120,  is_blob => 0,  is_numeric => 0,  type => 'varchar(120)', default => ''},
+        {read => 1, write => 1, sql_type => 12, length => 120,  is_blob => 0,  is_numeric => 0,  type => 'varchar(120)', default => '', is_case_sensitive => 0},
         CommentAddress => 
-        {read => 1, write => 1, sql_type => 12, length => 120,  is_blob => 0,  is_numeric => 0,  type => 'varchar(120)', default => ''},
+        {read => 1, write => 1, sql_type => 12, length => 120,  is_blob => 0,  is_numeric => 0,  type => 'varchar(120)', default => '', is_case_sensitive => 0},
         SubjectTag => 
-        {read => 1, write => 1, sql_type => 12, length => 120,  is_blob => 0,  is_numeric => 0,  type => 'varchar(120)', default => ''},
+        {read => 1, write => 1, sql_type => 12, length => 120,  is_blob => 0,  is_numeric => 0,  type => 'varchar(120)', default => '', is_case_sensitive => 0},
         Lifecycle => 
-        {read => 1, write => 1, sql_type => 12, length => 32,  is_blob => 0, is_numeric => 0,  type => 'varchar(32)', default => 'default'},
+        {read => 1, write => 1, sql_type => 12, length => 32,  is_blob => 0, is_numeric => 0,  type => 'varchar(32)', default => 'default', is_case_sensitive => 0},
         SortOrder => 
         {read => 1, write => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => '0'},
         Creator => 
diff --git a/lib/RT/Scrip.pm b/lib/RT/Scrip.pm
index dd488f6730..b930a57096 100644
--- a/lib/RT/Scrip.pm
+++ b/lib/RT/Scrip.pm
@@ -1079,11 +1079,11 @@ sub _CoreAccessible {
         id =>
                 {read => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => ''},
         Description =>
-                {read => 1, write => 1, sql_type => 12, length => 255,  is_blob => 0,  is_numeric => 0,  type => 'varchar(255)', default => ''},
+                {read => 1, write => 1, sql_type => 12, length => 255,  is_blob => 0,  is_numeric => 0,  type => 'varchar(255)', default => '', is_case_sensitive => 0},
         ScripCondition =>
-                {read => 1, write => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => '0'},
+                {read => 1, write => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => '0', is_case_sensitive => 0},
         ScripAction =>
-                {read => 1, write => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => '0'},
+                {read => 1, write => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => '0', is_case_sensitive => 0},
         CustomIsApplicableCode =>
                 {read => 1, write => 1, sql_type => -4, length => 0,  is_blob => 1,  is_numeric => 0,  type => 'text', default => ''},
         CustomPrepareCode =>
@@ -1093,7 +1093,7 @@ sub _CoreAccessible {
         Disabled =>
                 {read => 1, write => 1, sql_type => 5, length => 6,  is_blob => 0,  is_numeric => 1,  type => 'smallint(6)', default => '0'},
         Template =>
-                {read => 1, write => 1, sql_type => 12, length => 200,  is_blob => 0,  is_numeric => 0,  type => 'varchar(200)', default => 'Blank'},
+                {read => 1, write => 1, sql_type => 12, length => 200,  is_blob => 0,  is_numeric => 0,  type => 'varchar(200)', default => 'Blank', is_case_sensitive => 0},
         Creator =>
                 {read => 1, auto => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => '0'},
         Created =>
diff --git a/lib/RT/ScripAction.pm b/lib/RT/ScripAction.pm
index 124db1ba24..833f9e6257 100644
--- a/lib/RT/ScripAction.pm
+++ b/lib/RT/ScripAction.pm
@@ -300,9 +300,9 @@ sub _CoreAccessible {
         id =>
                 {read => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => ''},
         Name =>
-                {read => 1, write => 1, sql_type => 12, length => 200,  is_blob => 0,  is_numeric => 0,  type => 'varchar(200)', default => ''},
+                {read => 1, write => 1, sql_type => 12, length => 200,  is_blob => 0,  is_numeric => 0,  type => 'varchar(200)', default => '', is_case_sensitive => 0},
         Description =>
-                {read => 1, write => 1, sql_type => 12, length => 255,  is_blob => 0,  is_numeric => 0,  type => 'varchar(255)', default => ''},
+                {read => 1, write => 1, sql_type => 12, length => 255,  is_blob => 0,  is_numeric => 0,  type => 'varchar(255)', default => '', is_case_sensitive => 0},
         ExecModule =>
                 {read => 1, write => 1, sql_type => 12, length => 60,  is_blob => 0,  is_numeric => 0,  type => 'varchar(60)', default => ''},
         Argument =>
diff --git a/lib/RT/ScripCondition.pm b/lib/RT/ScripCondition.pm
index 3aadd65871..e3664a7f09 100644
--- a/lib/RT/ScripCondition.pm
+++ b/lib/RT/ScripCondition.pm
@@ -361,9 +361,9 @@ sub _CoreAccessible {
         id =>
                 {read => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => ''},
         Name =>
-                {read => 1, write => 1, sql_type => 12, length => 200,  is_blob => 0,  is_numeric => 0,  type => 'varchar(200)', default => ''},
+                {read => 1, write => 1, sql_type => 12, length => 200,  is_blob => 0,  is_numeric => 0,  type => 'varchar(200)', default => '', is_case_sensitive => 0},
         Description =>
-                {read => 1, write => 1, sql_type => 12, length => 255,  is_blob => 0,  is_numeric => 0,  type => 'varchar(255)', default => ''},
+                {read => 1, write => 1, sql_type => 12, length => 255,  is_blob => 0,  is_numeric => 0,  type => 'varchar(255)', default => '', is_case_sensitive => 0},
         ExecModule =>
                 {read => 1, write => 1, sql_type => 12, length => 60,  is_blob => 0,  is_numeric => 0,  type => 'varchar(60)', default => ''},
         Argument =>
diff --git a/lib/RT/Template.pm b/lib/RT/Template.pm
index 2155bf4296..fced4dfc6c 100644
--- a/lib/RT/Template.pm
+++ b/lib/RT/Template.pm
@@ -1041,9 +1041,9 @@ sub _CoreAccessible {
         Queue =>
                 {read => 1, write => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => '0'},
         Name =>
-                {read => 1, write => 1, sql_type => 12, length => 200,  is_blob => 0,  is_numeric => 0,  type => 'varchar(200)', default => ''},
+                {read => 1, write => 1, sql_type => 12, length => 200,  is_blob => 0,  is_numeric => 0,  type => 'varchar(200)', default => '', is_case_sensitive => 0},
         Description =>
-                {read => 1, write => 1, sql_type => 12, length => 255,  is_blob => 0,  is_numeric => 0,  type => 'varchar(255)', default => ''},
+                {read => 1, write => 1, sql_type => 12, length => 255,  is_blob => 0,  is_numeric => 0,  type => 'varchar(255)', default => '', is_case_sensitive => 0},
         Type =>
                 {read => 1, write => 1, sql_type => 12, length => 16,  is_blob => 0,  is_numeric => 0,  type => 'varchar(16)', default => ''},
         Content =>
diff --git a/lib/RT/Ticket.pm b/lib/RT/Ticket.pm
index 76af2da40d..1a84820fb5 100644
--- a/lib/RT/Ticket.pm
+++ b/lib/RT/Ticket.pm
@@ -3672,7 +3672,7 @@ sub _CoreAccessible {
         Owner =>
                 {read => 1, write => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => '0'},
         Subject =>
-                {read => 1, write => 1, sql_type => 12, length => 200,  is_blob => 0,  is_numeric => 0,  type => 'varchar(200)', default => '[no subject]'},
+                {read => 1, write => 1, sql_type => 12, length => 200,  is_blob => 0,  is_numeric => 0,  type => 'varchar(200)', default => '[no subject]', is_case_sensitive => 0},
         InitialPriority =>
                 {read => 1, write => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => '0'},
         FinalPriority =>
@@ -3686,7 +3686,7 @@ sub _CoreAccessible {
         Status =>
                 {read => 1, write => 1, sql_type => 12, length => 64,  is_blob => 0,  is_numeric => 0,  type => 'varchar(64)', default => '', is_case_sensitive => 0},
         SLA =>
-                {read => 1, write => 1, sql_type => 12, length => 64,  is_blob => 0,  is_numeric => 0,  type => 'varchar(64)', default => ''},
+                {read => 1, write => 1, sql_type => 12, length => 64,  is_blob => 0,  is_numeric => 0,  type => 'varchar(64)', default => '', is_case_sensitive => 0},
         TimeLeft =>
                 {read => 1, write => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => '0'},
         Told =>
diff --git a/lib/RT/Topic.pm b/lib/RT/Topic.pm
index 79edc1511f..f03e823f67 100644
--- a/lib/RT/Topic.pm
+++ b/lib/RT/Topic.pm
@@ -341,9 +341,9 @@ sub _CoreAccessible {
         Parent => 
                 {read => 1, write => 1, type => 'int(11)', default => ''},
         Name => 
-                {read => 1, write => 1, type => 'varchar(255)', default => ''},
+                {read => 1, write => 1, type => 'varchar(255)', default => '', is_case_sensitive => 0},
         Description => 
-                {read => 1, write => 1, type => 'varchar(255)', default => ''},
+                {read => 1, write => 1, type => 'varchar(255)', default => '', is_case_sensitive => 0},
         ObjectType => 
                 {read => 1, write => 1, type => 'varchar(64)', default => ''},
         ObjectId => 
diff --git a/lib/RT/Transaction.pm b/lib/RT/Transaction.pm
index 526a90bfb0..51e1f7501d 100644
--- a/lib/RT/Transaction.pm
+++ b/lib/RT/Transaction.pm
@@ -2083,9 +2083,9 @@ sub _CoreAccessible {
         Field =>
                 {read => 1, write => 1, sql_type => 12, length => 255,  is_blob => 0,  is_numeric => 0,  type => 'varchar(255)', default => ''},
         OldValue =>
-                {read => 1, write => 1, sql_type => 12, length => 255,  is_blob => 0,  is_numeric => 0,  type => 'varchar(255)', default => ''},
+                {read => 1, write => 1, sql_type => 12, length => 255,  is_blob => 0,  is_numeric => 0,  type => 'varchar(255)', default => '', is_case_sensitive => 0},
         NewValue =>
-                {read => 1, write => 1, sql_type => 12, length => 255,  is_blob => 0,  is_numeric => 0,  type => 'varchar(255)', default => ''},
+                {read => 1, write => 1, sql_type => 12, length => 255,  is_blob => 0,  is_numeric => 0,  type => 'varchar(255)', default => '', is_case_sensitive => 0},
         ReferenceType =>
                 {read => 1, write => 1, sql_type => 12, length => 255,  is_blob => 0,  is_numeric => 0,  type => 'varchar(255)', default => ''},
         OldReference =>
@@ -2093,7 +2093,7 @@ sub _CoreAccessible {
         NewReference =>
                 {read => 1, write => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => ''},
         Data =>
-                {read => 1, write => 1, sql_type => 12, length => 255,  is_blob => 0,  is_numeric => 0,  type => 'varchar(255)', default => ''},
+                {read => 1, write => 1, sql_type => 12, length => 255,  is_blob => 0,  is_numeric => 0,  type => 'varchar(255)', default => '', is_case_sensitive => 0},
         Creator =>
                 {read => 1, auto => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => '0'},
         Created =>
diff --git a/lib/RT/User.pm b/lib/RT/User.pm
index 2d4986365a..b34565dc40 100644
--- a/lib/RT/User.pm
+++ b/lib/RT/User.pm
@@ -2869,45 +2869,45 @@ sub _CoreAccessible {
         AuthToken => 
         {read => 1, write => 1, sql_type => 12, length => 16,  is_blob => 0,  is_numeric => 0,  type => 'varchar(16)', default => ''},
         Comments => 
-        {read => 1, write => 1, sql_type => -4, length => 0,  is_blob => 1,  is_numeric => 0,  type => 'text', default => ''},
+        {read => 1, write => 1, sql_type => -4, length => 0,  is_blob => 1,  is_numeric => 0,  type => 'text', default => '', is_case_sensitive => 0},
         Signature => 
-        {read => 1, write => 1, sql_type => -4, length => 0,  is_blob => 1,  is_numeric => 0,  type => 'text', default => ''},
+        {read => 1, write => 1, sql_type => -4, length => 0,  is_blob => 1,  is_numeric => 0,  type => 'text', default => '', is_case_sensitive => 0},
         EmailAddress => 
         {read => 1, write => 1, sql_type => 12, length => 120,  is_blob => 0,  is_numeric => 0,  type => 'varchar(120)', default => '', is_case_sensitive => 0},
         FreeformContactInfo => 
         {read => 1, write => 1, sql_type => -4, length => 0,  is_blob => 1,  is_numeric => 0,  type => 'text', default => ''},
         Organization => 
-        {read => 1, write => 1, sql_type => 12, length => 200,  is_blob => 0,  is_numeric => 0,  type => 'varchar(200)', default => ''},
+        {read => 1, write => 1, sql_type => 12, length => 200,  is_blob => 0,  is_numeric => 0,  type => 'varchar(200)', default => '', is_case_sensitive => 0},
         RealName => 
-        {read => 1, write => 1, sql_type => 12, length => 120,  is_blob => 0,  is_numeric => 0,  type => 'varchar(120)', default => ''},
+        {read => 1, write => 1, sql_type => 12, length => 120,  is_blob => 0,  is_numeric => 0,  type => 'varchar(120)', default => '', is_case_sensitive => 0},
         NickName => 
-        {read => 1, write => 1, sql_type => 12, length => 16,  is_blob => 0,  is_numeric => 0,  type => 'varchar(16)', default => ''},
+        {read => 1, write => 1, sql_type => 12, length => 16,  is_blob => 0,  is_numeric => 0,  type => 'varchar(16)', default => '', is_case_sensitive => 0},
         Lang => 
-        {read => 1, write => 1, sql_type => 12, length => 16,  is_blob => 0,  is_numeric => 0,  type => 'varchar(16)', default => ''},
+        {read => 1, write => 1, sql_type => 12, length => 16,  is_blob => 0,  is_numeric => 0,  type => 'varchar(16)', default => '', is_case_sensitive => 0},
         Gecos => 
-        {read => 1, write => 1, sql_type => 12, length => 16,  is_blob => 0,  is_numeric => 0,  type => 'varchar(16)', default => ''},
+        {read => 1, write => 1, sql_type => 12, length => 16,  is_blob => 0,  is_numeric => 0,  type => 'varchar(16)', default => '', is_case_sensitive => 0},
         HomePhone => 
-        {read => 1, write => 1, sql_type => 12, length => 30,  is_blob => 0,  is_numeric => 0,  type => 'varchar(30)', default => ''},
+        {read => 1, write => 1, sql_type => 12, length => 30,  is_blob => 0,  is_numeric => 0,  type => 'varchar(30)', default => '', is_case_sensitive => 0},
         WorkPhone => 
-        {read => 1, write => 1, sql_type => 12, length => 30,  is_blob => 0,  is_numeric => 0,  type => 'varchar(30)', default => ''},
+        {read => 1, write => 1, sql_type => 12, length => 30,  is_blob => 0,  is_numeric => 0,  type => 'varchar(30)', default => '', is_case_sensitive => 0},
         MobilePhone => 
-        {read => 1, write => 1, sql_type => 12, length => 30,  is_blob => 0,  is_numeric => 0,  type => 'varchar(30)', default => ''},
+        {read => 1, write => 1, sql_type => 12, length => 30,  is_blob => 0,  is_numeric => 0,  type => 'varchar(30)', default => '', is_case_sensitive => 0},
         PagerPhone => 
-        {read => 1, write => 1, sql_type => 12, length => 30,  is_blob => 0,  is_numeric => 0,  type => 'varchar(30)', default => ''},
+        {read => 1, write => 1, sql_type => 12, length => 30,  is_blob => 0,  is_numeric => 0,  type => 'varchar(30)', default => '', is_case_sensitive => 0},
         Address1 => 
-        {read => 1, write => 1, sql_type => 12, length => 200,  is_blob => 0,  is_numeric => 0,  type => 'varchar(200)', default => ''},
+        {read => 1, write => 1, sql_type => 12, length => 200,  is_blob => 0,  is_numeric => 0,  type => 'varchar(200)', default => '', is_case_sensitive => 0},
         Address2 => 
-        {read => 1, write => 1, sql_type => 12, length => 200,  is_blob => 0,  is_numeric => 0,  type => 'varchar(200)', default => ''},
+        {read => 1, write => 1, sql_type => 12, length => 200,  is_blob => 0,  is_numeric => 0,  type => 'varchar(200)', default => '', is_case_sensitive => 0},
         City => 
-        {read => 1, write => 1, sql_type => 12, length => 100,  is_blob => 0,  is_numeric => 0,  type => 'varchar(100)', default => ''},
+        {read => 1, write => 1, sql_type => 12, length => 100,  is_blob => 0,  is_numeric => 0,  type => 'varchar(100)', default => '', is_case_sensitive => 0},
         State => 
-        {read => 1, write => 1, sql_type => 12, length => 100,  is_blob => 0,  is_numeric => 0,  type => 'varchar(100)', default => ''},
+        {read => 1, write => 1, sql_type => 12, length => 100,  is_blob => 0,  is_numeric => 0,  type => 'varchar(100)', default => '', is_case_sensitive => 0},
         Zip => 
-        {read => 1, write => 1, sql_type => 12, length => 16,  is_blob => 0,  is_numeric => 0,  type => 'varchar(16)', default => ''},
+        {read => 1, write => 1, sql_type => 12, length => 16,  is_blob => 0,  is_numeric => 0,  type => 'varchar(16)', default => '', is_case_sensitive => 0},
         Country => 
-        {read => 1, write => 1, sql_type => 12, length => 50,  is_blob => 0,  is_numeric => 0,  type => 'varchar(50)', default => ''},
+        {read => 1, write => 1, sql_type => 12, length => 50,  is_blob => 0,  is_numeric => 0,  type => 'varchar(50)', default => '', is_case_sensitive => 0},
         Timezone => 
-        {read => 1, write => 1, sql_type => 12, length => 50,  is_blob => 0,  is_numeric => 0,  type => 'varchar(50)', default => ''},
+        {read => 1, write => 1, sql_type => 12, length => 50,  is_blob => 0,  is_numeric => 0,  type => 'varchar(50)', default => '', is_case_sensitive => 0},
         SMIMECertificate =>
         {read => 1, write => 1, sql_type => -4, length => 0,  is_blob => 1,  is_numeric => 0,  type => 'text', default => ''},
         Creator => 

commit 44c64a1f24440be68ce7e7be68ec00816cca206e
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Sat Oct 1 03:27:01 2022 +0800

    Support case insensitive "IN" searches for all fields
    
    Previously we implemented it only for specifiec fields like group names,
    this commit abstracts it so it could be used for all case insensitive
    fields.
    
    Ideally this shall be done in DBIx::SearchBuilder, which doesn't respect
    CASESENSITIVE => 0 for "IN" operator yet. We can probably consider
    improving DBIx::SearchBuilder on next big version jump.
    
    See also b14df0ee4f

diff --git a/lib/RT/Assets.pm b/lib/RT/Assets.pm
index 8698cf00c0..bc9f942073 100644
--- a/lib/RT/Assets.pm
+++ b/lib/RT/Assets.pm
@@ -696,10 +696,8 @@ sub CurrentUserCanSee {
         $groups->Limit( FIELD => 'Domain', VALUE => 'RT::Catalog-Role', CASESENSITIVE => 0 );
         $groups->Limit(
             FIELD         => 'Name',
-            FUNCTION      => 'LOWER(?)',
             OPERATOR      => 'IN',
-            VALUE         => [ map {lc $_} @tmp ],
-            CASESENSITIVE => 1,
+            VALUE         => \@tmp,
         );
         my $principal_alias = $groups->Join(
             ALIAS1 => 'main',
diff --git a/lib/RT/CustomFields.pm b/lib/RT/CustomFields.pm
index 7615799052..56d11cac44 100644
--- a/lib/RT/CustomFields.pm
+++ b/lib/RT/CustomFields.pm
@@ -151,10 +151,8 @@ sub LimitToGrouping {
         }
         $self->Limit(
             FIELD         => 'Name',
-            FUNCTION      => 'LOWER(?)',
             OPERATOR      => 'IN',
-            VALUE         => [map {lc $_} @{$list}],
-            CASESENSITIVE => 1,
+            VALUE         => $list,
         );
     } else {
         my @list = map {@$_} grep defined && ref($_) eq 'ARRAY',
@@ -164,10 +162,8 @@ sub LimitToGrouping {
 
         $self->Limit(
             FIELD         => 'Name',
-            FUNCTION      => 'LOWER(?)',
             OPERATOR      => 'NOT IN',
-            VALUE         => [ map {lc $_} @list ],
-            CASESENSITIVE => 1,
+            VALUE         => \@list,
         );
     }
     return;
diff --git a/lib/RT/Interface/Web.pm b/lib/RT/Interface/Web.pm
index 17dfc131e2..1b02ba5da6 100644
--- a/lib/RT/Interface/Web.pm
+++ b/lib/RT/Interface/Web.pm
@@ -4259,10 +4259,8 @@ sub GetPrincipalsMap {
                     $roles->LimitToRolesForObject(RT->System);
                     $roles->Limit(
                         FIELD         => "Name",
-                        FUNCTION      => 'LOWER(?)',
                         OPERATOR      => "IN",
-                        VALUE         => [ map {lc $_} $class->Roles ],
-                        CASESENSITIVE => 1,
+                        VALUE         => [ $class->Roles ],
                     );
                 } else {
                     # No roles to show; so show nothing
diff --git a/lib/RT/SearchBuilder.pm b/lib/RT/SearchBuilder.pm
index 358e5577a7..73178740f8 100644
--- a/lib/RT/SearchBuilder.pm
+++ b/lib/RT/SearchBuilder.pm
@@ -993,6 +993,23 @@ sub Limit {
         $ARGS{'CASESENSITIVE'} //= 1;
     }
 
+    # DBIx::SearchBuilder(current version is 1.74) doesn't respect CASESENSITIVE => 0 for IN operator.
+    # Convert IN searches like "Status IN ( 'new', 'open' )" to "LOWER(Status) IN ( 'new', 'open' )"
+    if (
+           $self->_Handle->CaseSensitive
+        && !$ARGS{CASESENSITIVE}
+        && !$ARGS{FUNCTION}
+        && $ARGS{OPERATOR} =~ /\bIN\b/i
+        && ( $ARGS{QUOTEVALUE} || !exists $ARGS{QUOTEVALUE} )    # QUOTEVALUE defaults to true in DBIx::SearchBuilder
+        && ref $ARGS{VALUE} eq 'ARRAY'
+        && grep( /\D/, @{ $ARGS{VALUE} } )
+        )
+    {
+        $ARGS{FUNCTION}      = 'LOWER(?)';
+        $ARGS{VALUE}         = [ map lc, @{ $ARGS{VALUE} } ];
+        $ARGS{CASESENSITIVE} = 1;
+    }
+
     # Oracle doesn't support to directly compare CLOB with VARCHAR/INTEGER.
     # DefaultDashboard search in RT::Dashboard::CurrentUserCanDelete needs this
     if (   $ARGS{OPERATOR} !~ /IS/i
diff --git a/lib/RT/Tickets.pm b/lib/RT/Tickets.pm
index e58ad24a28..bf2540efcc 100644
--- a/lib/RT/Tickets.pm
+++ b/lib/RT/Tickets.pm
@@ -2794,10 +2794,8 @@ sub CurrentUserCanSee {
         $groups->Limit( FIELD => 'Domain', VALUE => 'RT::Queue-Role', CASESENSITIVE => 0 );
         $groups->Limit(
             FIELD         => 'Name',
-            FUNCTION      => 'LOWER(?)',
             OPERATOR      => 'IN',
-            VALUE         => [ map {lc $_} @tmp ],
-            CASESENSITIVE => 1,
+            VALUE         => \@tmp,
         );
         my $principal_alias = $groups->Join(
             ALIAS1 => 'main',

commit 2591be50b1b1ecc1c9b23d56f1f582a4afe3af1f
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Fri Sep 30 23:08:49 2022 +0800

    Default searches to be case insensitive for fields with lower cased indexes
    
    Previously we had to manually pass CASESENSITIVE arg. We don't need to
    do so any more with this commit.

diff --git a/lib/RT/Asset.pm b/lib/RT/Asset.pm
index c29e58f67d..68bb48fb74 100644
--- a/lib/RT/Asset.pm
+++ b/lib/RT/Asset.pm
@@ -689,8 +689,8 @@ sub Table { "Assets" }
 sub _CoreAccessible {
     {
         id            => { read => 1, type => 'int(11)',        default => '' },
-        Name          => { read => 1, type => 'varchar(255)',   default => '',  write => 1 },
-        Status        => { read => 1, type => 'varchar(64)',    default => '',  write => 1 },
+        Name          => { read => 1, type => 'varchar(255)',   default => '',  write => 1, is_case_sensitive => 0 },
+        Status        => { read => 1, type => 'varchar(64)',    default => '',  write => 1, is_case_sensitive => 0 },
         Description   => { read => 1, type => 'varchar(255)',   default => '',  write => 1 },
         Catalog       => { read => 1, type => 'int(11)',        default => '0', write => 1 },
         Creator       => { read => 1, type => 'int(11)',        default => '0', auto => 1 },
diff --git a/lib/RT/Attachment.pm b/lib/RT/Attachment.pm
index 03af410a5b..5254c2c407 100644
--- a/lib/RT/Attachment.pm
+++ b/lib/RT/Attachment.pm
@@ -1296,7 +1296,7 @@ sub _CoreAccessible {
         Subject =>
                 {read => 1, write => 1, sql_type => 12, length => 255,  is_blob => 0,  is_numeric => 0,  type => 'varchar(255)', default => ''},
         Filename =>
-                {read => 1, write => 1, sql_type => 12, length => 255,  is_blob => 0,  is_numeric => 0,  type => 'varchar(255)', default => ''},
+                {read => 1, write => 1, sql_type => 12, length => 255,  is_blob => 0,  is_numeric => 0,  type => 'varchar(255)', default => '', is_case_sensitive => 0},
         ContentType =>
                 {read => 1, write => 1, sql_type => 12, length => 80,  is_blob => 0,  is_numeric => 0,  type => 'varchar(80)', default => ''},
         ContentEncoding =>
diff --git a/lib/RT/Catalog.pm b/lib/RT/Catalog.pm
index 415042330d..52b3102b1d 100644
--- a/lib/RT/Catalog.pm
+++ b/lib/RT/Catalog.pm
@@ -488,7 +488,7 @@ sub Table { "Catalogs" }
 sub _CoreAccessible {
     {
         id            => { read => 1, type => 'int(11)',        default => '' },
-        Name          => { read => 1, type => 'varchar(255)',   default => '',          write => 1 },
+        Name          => { read => 1, type => 'varchar(255)',   default => '',          write => 1, is_case_sensitive => 0 },
         Description   => { read => 1, type => 'varchar(255)',   default => '',          write => 1 },
         Lifecycle     => { read => 1, type => 'varchar(32)',    default => 'assets',    write => 1 },
         Disabled      => { read => 1, type => 'int(2)',         default => '0',         write => 1 },
diff --git a/lib/RT/Configuration.pm b/lib/RT/Configuration.pm
index 2952e251b4..9fd0e91c85 100644
--- a/lib/RT/Configuration.pm
+++ b/lib/RT/Configuration.pm
@@ -499,7 +499,7 @@ sub Table { "Configurations" }
 sub _CoreAccessible {
     {
         id            => { read => 1, type => 'int(11)',        default => '' },
-        Name          => { read => 1, sql_type => 12, length => 255,  is_blob => 0,  is_numeric => 0,  type => 'varchar(255)', default => ''},
+        Name          => { read => 1, sql_type => 12, length => 255,  is_blob => 0,  is_numeric => 0,  type => 'varchar(255)', default => '', is_case_sensitive => 0},
         Content       => { read => 1, write => 1, sql_type => -4, length => 0,  is_blob => 1,  is_numeric => 0,  type => 'blob', default => ''},
         ContentType   => { read => 1, write => 1, sql_type => 12, length => 16,  is_blob => 0,  is_numeric => 0,  type => 'varchar(16)', default => ''},
         Disabled      => { read => 1, write => 1, sql_type => 5, length => 6,  is_blob => 0,  is_numeric => 1,  type => 'smallint(6)', default => '0'},
diff --git a/lib/RT/Group.pm b/lib/RT/Group.pm
index 9fc202d001..28d2452d9c 100644
--- a/lib/RT/Group.pm
+++ b/lib/RT/Group.pm
@@ -1526,11 +1526,11 @@ sub _CoreAccessible {
         id =>
                 {read => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => ''},
         Name =>
-                {read => 1, write => 1, sql_type => 12, length => 200,  is_blob => 0,  is_numeric => 0,  type => 'varchar(200)', default => ''},
+                {read => 1, write => 1, sql_type => 12, length => 200,  is_blob => 0,  is_numeric => 0,  type => 'varchar(200)', default => '', is_case_sensitive => 0},
         Description =>
                 {read => 1, write => 1, sql_type => 12, length => 255,  is_blob => 0,  is_numeric => 0,  type => 'varchar(255)', default => ''},
         Domain =>
-                {read => 1, write => 1, sql_type => 12, length => 64,  is_blob => 0,  is_numeric => 0,  type => 'varchar(64)', default => ''},
+                {read => 1, write => 1, sql_type => 12, length => 64,  is_blob => 0,  is_numeric => 0,  type => 'varchar(64)', default => '', is_case_sensitive => 0},
         Instance =>
                 {read => 1, write => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => ''},
         Creator =>
diff --git a/lib/RT/ObjectCustomFieldValue.pm b/lib/RT/ObjectCustomFieldValue.pm
index e28c33765c..1f8eba5680 100644
--- a/lib/RT/ObjectCustomFieldValue.pm
+++ b/lib/RT/ObjectCustomFieldValue.pm
@@ -750,7 +750,7 @@ sub _CoreAccessible {
         SortOrder =>
                 {read => 1, write => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => '0'},
         Content =>
-                {read => 1, write => 1, sql_type => 12, length => 255,  is_blob => 0,  is_numeric => 0,  type => 'varchar(255)', default => ''},
+                {read => 1, write => 1, sql_type => 12, length => 255,  is_blob => 0,  is_numeric => 0,  type => 'varchar(255)', default => '', is_case_sensitive => 0},
         LargeContent =>
                 {read => 1, write => 1, sql_type => -4, length => 0,  is_blob => 1,  is_numeric => 0,  type => 'longblob', default => ''},
         ContentType =>
diff --git a/lib/RT/Queue.pm b/lib/RT/Queue.pm
index 1f3af9c9d0..08d45e89f4 100644
--- a/lib/RT/Queue.pm
+++ b/lib/RT/Queue.pm
@@ -995,7 +995,7 @@ sub _CoreAccessible {
         id =>
         {read => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => ''},
         Name => 
-        {read => 1, write => 1, sql_type => 12, length => 200,  is_blob => 0,  is_numeric => 0,  type => 'varchar(200)', default => ''},
+        {read => 1, write => 1, sql_type => 12, length => 200,  is_blob => 0,  is_numeric => 0,  type => 'varchar(200)', default => '', is_case_sensitive => 0 },
         Description => 
         {read => 1, write => 1, sql_type => 12, length => 255,  is_blob => 0,  is_numeric => 0,  type => 'varchar(255)', default => ''},
         CorrespondAddress => 
diff --git a/lib/RT/SearchBuilder.pm b/lib/RT/SearchBuilder.pm
index 4a740d73b5..358e5577a7 100644
--- a/lib/RT/SearchBuilder.pm
+++ b/lib/RT/SearchBuilder.pm
@@ -932,13 +932,6 @@ injection attacks when we pass through user specified values.
 
 =cut
 
-my %check_case_sensitivity = (
-    groups => { 'name' => 1, domain => 1 },
-    queues => { 'name' => 1 },
-    users => { 'name' => 1, emailaddress => 1 },
-    customfields => { 'name' => 1 },
-);
-
 my %deprecated = (
 );
 
@@ -988,15 +981,16 @@ sub Limit {
     }
 
     unless ( exists $ARGS{CASESENSITIVE} or (exists $ARGS{QUOTEVALUE} and not $ARGS{QUOTEVALUE}) ) {
-        if ( $ARGS{FIELD} and $ARGS{'OPERATOR'} !~ /IS/i
-            && $table && $check_case_sensitivity{ lc $table }{ lc $ARGS{'FIELD'} }
-        ) {
-            RT->Logger->warning(
-                "Case sensitive search by $table.$ARGS{'FIELD'}"
-                ." at ". (caller)[1] . " line ". (caller)[2]
-            );
+
+        # Set CASESENSITIVE from field declaration
+        my $class = "RT::$table";
+        if ( $class->can('RecordClass') && $class->RecordClass && $class->RecordClass->can('_ClassAccessible') ) {
+            if ( my $meta = $class->RecordClass->_ClassAccessible->{ $ARGS{FIELD} } ) {
+                $ARGS{'CASESENSITIVE'} = $meta->{is_case_sensitive};
+            }
         }
-        $ARGS{'CASESENSITIVE'} = 1;
+
+        $ARGS{'CASESENSITIVE'} //= 1;
     }
 
     # Oracle doesn't support to directly compare CLOB with VARCHAR/INTEGER.
diff --git a/lib/RT/Ticket.pm b/lib/RT/Ticket.pm
index 5592929bb3..76af2da40d 100644
--- a/lib/RT/Ticket.pm
+++ b/lib/RT/Ticket.pm
@@ -3684,7 +3684,7 @@ sub _CoreAccessible {
         TimeWorked =>
                 {read => 1, write => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => '0'},
         Status =>
-                {read => 1, write => 1, sql_type => 12, length => 64,  is_blob => 0,  is_numeric => 0,  type => 'varchar(64)', default => ''},
+                {read => 1, write => 1, sql_type => 12, length => 64,  is_blob => 0,  is_numeric => 0,  type => 'varchar(64)', default => '', is_case_sensitive => 0},
         SLA =>
                 {read => 1, write => 1, sql_type => 12, length => 64,  is_blob => 0,  is_numeric => 0,  type => 'varchar(64)', default => ''},
         TimeLeft =>
diff --git a/lib/RT/User.pm b/lib/RT/User.pm
index 7134085a66..2d4986365a 100644
--- a/lib/RT/User.pm
+++ b/lib/RT/User.pm
@@ -2863,7 +2863,7 @@ sub _CoreAccessible {
         id =>
         {read => 1, sql_type => 4, length => 11,  is_blob => 0,  is_numeric => 1,  type => 'int(11)', default => ''},
         Name => 
-        {read => 1, write => 1, sql_type => 12, length => 200,  is_blob => 0,  is_numeric => 0,  type => 'varchar(200)', default => ''},
+        {read => 1, write => 1, sql_type => 12, length => 200,  is_blob => 0,  is_numeric => 0,  type => 'varchar(200)', default => '', is_case_sensitive => 0},
         Password => 
         {read => 1, write => 1, sql_type => 12, length => 256,  is_blob => 0,  is_numeric => 0,  type => 'varchar(256)', default => ''},
         AuthToken => 
@@ -2873,7 +2873,7 @@ sub _CoreAccessible {
         Signature => 
         {read => 1, write => 1, sql_type => -4, length => 0,  is_blob => 1,  is_numeric => 0,  type => 'text', default => ''},
         EmailAddress => 
-        {read => 1, write => 1, sql_type => 12, length => 120,  is_blob => 0,  is_numeric => 0,  type => 'varchar(120)', default => ''},
+        {read => 1, write => 1, sql_type => 12, length => 120,  is_blob => 0,  is_numeric => 0,  type => 'varchar(120)', default => '', is_case_sensitive => 0},
         FreeformContactInfo => 
         {read => 1, write => 1, sql_type => -4, length => 0,  is_blob => 1,  is_numeric => 0,  type => 'text', default => ''},
         Organization => 

commit 7c484af3787b68be9533ea9d1fd485e2d6dd4833
Author: sunnavy <sunnavy at bestpractical.com>
Date:   Tue Mar 28 05:46:59 2023 +0800

    Add missing classes to build all table attributes in advance
    
    With this, we can safely call _ClassAccessible to get attributes.

diff --git a/lib/RT.pm b/lib/RT.pm
index 32384704e3..bea08348a6 100644
--- a/lib/RT.pm
+++ b/lib/RT.pm
@@ -569,6 +569,10 @@ sub _BuildTableAttributes {
         RT::Catalog
         RT::CustomRole
         RT::ObjectCustomRole
+        RT::AuthToken
+        RT::CachedGroupMember
+        RT::Configuration
+        RT::CurrentUser
     );
 }
 

commit 0e87746b04be010bc488122aaeefbf9fc648b5d0
Author: Brian Conry <bconry at bestpractical.com>
Date:   Wed Mar 30 14:03:10 2022 -0500

    Make lower cased indexes on char columns that contain user inputs for Oracle
    
    Now that we're searching them with LOWER(), we need the lower cased
    indexes accordingly.

diff --git a/etc/schema.Oracle b/etc/schema.Oracle
index 7b7ac07475..1c2e205305 100644
--- a/etc/schema.Oracle
+++ b/etc/schema.Oracle
@@ -17,7 +17,7 @@ CREATE TABLE Attachments (
 );
 CREATE INDEX Attachments2 ON Attachments (TransactionId);
 CREATE INDEX Attachments3 ON Attachments (Parent, TransactionId);
-CREATE INDEX Attachments4 ON Attachments (Filename);
+CREATE INDEX Attachments4 ON Attachments (LOWER(Filename));
 
 
 CREATE SEQUENCE QUEUES_seq;
@@ -271,7 +271,7 @@ CREATE TABLE Tickets (
         Creator                 NUMBER(11,0) DEFAULT 0 NOT NULL,
         Created                 DATE
 );
-CREATE INDEX Tickets1 ON Tickets (Queue, Status);
+CREATE INDEX Tickets1 ON Tickets (Queue, LOWER(Status));
 CREATE INDEX Tickets2 ON Tickets (Owner);
 CREATE INDEX Tickets6 ON Tickets (EffectiveId, Type);
 
@@ -342,7 +342,7 @@ CREATE TABLE ObjectCustomFieldValues (
         Disabled        NUMBER(11,0) DEFAULT 0 NOT NULL
 );
 
-CREATE INDEX ObjectCustomFieldValues1 ON ObjectCustomFieldValues (Content); 
+CREATE INDEX ObjectCustomFieldValues1 ON ObjectCustomFieldValues (LOWER(Content)); 
 CREATE INDEX ObjectCustomFieldValues2 ON ObjectCustomFieldValues (CustomField,ObjectType,ObjectId); 
 
 CREATE SEQUENCE CUSTOMFIELDS_seq;
@@ -493,7 +493,7 @@ CREATE TABLE Assets (
 );
 
 CREATE INDEX AssetsName ON Assets (LOWER(Name));
-CREATE INDEX AssetsStatus ON Assets (Status);
+CREATE INDEX AssetsStatus ON Assets (LOWER(Status));
 CREATE INDEX AssetsCatalog ON Assets (Catalog);
 
 CREATE SEQUENCE Catalogs_seq;
diff --git a/etc/upgrade/5.0.4/schema.Oracle b/etc/upgrade/5.0.4/schema.Oracle
index 300bf8d8b6..67c43908b3 100644
--- a/etc/upgrade/5.0.4/schema.Oracle
+++ b/etc/upgrade/5.0.4/schema.Oracle
@@ -1,2 +1,10 @@
 ALTER TABLE CustomRoles ADD LookupType VARCHAR2(255);
 UPDATE CustomRoles SET LookupType='RT::Queue-RT::Ticket';
+DROP INDEX Tickets1;
+CREATE INDEX Tickets1 ON Tickets (Queue, LOWER(Status));
+DROP INDEX AssetsStatus;
+CREATE INDEX AssetsStatus ON Assets (LOWER(Status));
+DROP INDEX Attachments4;
+CREATE INDEX Attachments4 ON Attachments (LOWER(Filename));
+DROP INDEX ObjectCustomFieldValues1;
+CREATE INDEX ObjectCustomFieldValues1 ON ObjectCustomFieldValues (LOWER(Content));

commit 8b312d02867650e65a892cd3ece8c87061e9fbfc
Author: Brian Conry <bconry at bestpractical.com>
Date:   Wed Mar 30 13:10:45 2022 -0500

    Make lower cased indexes on char columns that contain user inputs for Pg
    
    Now that we're searching them with LOWER(), we need the lower cased
    indexes accordingly.

diff --git a/etc/schema.Pg b/etc/schema.Pg
index 0c81859312..ba470daeb6 100644
--- a/etc/schema.Pg
+++ b/etc/schema.Pg
@@ -33,7 +33,7 @@ CREATE TABLE Attachments (
 CREATE INDEX Attachments1 ON Attachments (Parent) ;
 CREATE INDEX Attachments2 ON Attachments (TransactionId) ;
 CREATE INDEX Attachments3 ON Attachments (Parent, TransactionId) ;
-CREATE INDEX Attachments4 ON Attachments (Filename) ;
+CREATE INDEX Attachments4 ON Attachments (LOWER(Filename));
 
 
 
@@ -429,7 +429,7 @@ CREATE TABLE Tickets (
 
 );
 
-CREATE INDEX Tickets1 ON Tickets (Queue, Status) ;
+CREATE INDEX Tickets1 ON Tickets (Queue, LOWER(Status));
 CREATE INDEX Tickets2 ON Tickets (Owner) ;
 CREATE INDEX Tickets3 ON Tickets (EffectiveId) ;
 
@@ -514,7 +514,7 @@ CREATE TABLE ObjectCustomFieldValues (
 
 );
 
-CREATE INDEX ObjectCustomFieldValues1 ON ObjectCustomFieldValues (CustomField,ObjectType,ObjectId,Content); 
+CREATE INDEX ObjectCustomFieldValues1 ON ObjectCustomFieldValues (CustomField,ObjectType,ObjectId,LOWER(Content)); 
 CREATE INDEX ObjectCustomFieldValues2 ON ObjectCustomFieldValues (CustomField,ObjectType,ObjectId); 
 
 
@@ -725,7 +725,7 @@ CREATE TABLE Assets (
 );
 
 CREATE INDEX AssetsName ON Assets (LOWER(Name));
-CREATE INDEX AssetsStatus ON Assets (Status);
+CREATE INDEX AssetsStatus ON Assets (LOWER(Status));
 CREATE INDEX AssetsCatalog ON Assets (Catalog);
 
 CREATE SEQUENCE catalogs_id_seq;
diff --git a/etc/upgrade/5.0.4/schema.Pg b/etc/upgrade/5.0.4/schema.Pg
index 671d871f45..196e86bb44 100644
--- a/etc/upgrade/5.0.4/schema.Pg
+++ b/etc/upgrade/5.0.4/schema.Pg
@@ -1,2 +1,10 @@
 ALTER TABLE CustomRoles ADD COLUMN LookupType VARCHAR(255);
 UPDATE CustomRoles SET LookupType='RT::Queue-RT::Ticket';
+DROP INDEX Tickets1;
+CREATE INDEX Tickets1 ON Tickets (Queue, LOWER(Status));
+DROP INDEX AssetsStatus;
+CREATE INDEX AssetsStatus ON Assets (LOWER(Status));
+DROP INDEX Attachments4;
+CREATE INDEX Attachments4 ON Attachments (LOWER(Filename));
+DROP INDEX ObjectCustomFieldValues1;
+CREATE INDEX ObjectCustomFieldValues1 ON ObjectCustomFieldValues (CustomField, ObjectType, ObjectId, LOWER(Content));

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


hooks/post-receive
-- 
rt


More information about the rt-commit mailing list