Bug in RT::Tickets::LimitMemberOf (3.0.12)

I discovered the following issue I do not (yet) have a solution for:

If I merge to tickets with children, say,

#100
with child #101

#200
with child #201

→ merge #200 into #100

I expect something like

#100
with child #101 and #201

Indeed, if I do

my $members = $Ticket->Members;
while (my $link = $members->Next) {
next unless($link->BaseURI->IsLocal);

}

I get both tickets listed.
However, using

my $MyTickets = new RT::Tickets ($session{‘CurrentUser’});
$MyTickets->LimitMemberOf($Ticket->Id);
while (my $link = $MyTickets->Next) {

}

I only get #101. Looks like a bug in “RT::tickets::LimitMemberOf”.
Anyone noticed this before and/or got a fix?

Best regards,

Ruediger Riediger

Dr. Ruediger Riediger Sun Microsystems GmbH
NSG - SunCERT Komturstr. 18a
mailto:Ruediger.Riediger@Sun.com D-12099 Berlin
NOTICE: This email message is for the sole use of the intended
recipient(s) and may contain confidential and privileged information.
Any unauthorized review, use, disclosure or distribution is prohibited.
If you are not the intended recipient, please contact the sender by
reply email and destroy all copies of the original message.
PGP 2048RSA/0x2C5020E9 964C E189 0FF0 8882 2BAB 65E2 6912 1FF2

Ruediger Riediger wrote:

I get both tickets listed.
However, using

my $MyTickets = new RT::Tickets ($session{‘CurrentUser’});
$MyTickets->LimitMemberOf($Ticket->Id);
I only get #101. Looks like a bug in “RT::tickets::LimitMemberOf”.
Anyone noticed this before and/or got a fix?

What version of RT?

signature.asc (189 Bytes)

Jesse Vincent wrote:

I get both tickets listed.
However, using

my $MyTickets = new RT::Tickets ($session{‘CurrentUser’});
$MyTickets->LimitMemberOf($Ticket->Id);
I only get #101. Looks like a bug in “RT::tickets::LimitMemberOf”.
Anyone noticed this before and/or got a fix?

What version of RT?

see subject: 3.0.12
I noticed this as RTIR uses the later while RT the first function to
list children.

Best regards,

Ruediger Riediger

Dr. Ruediger Riediger Sun Microsystems GmbH
NSG - SunCERT Komturstr. 18a
mailto:Ruediger.Riediger@Sun.com D-12099 Berlin
NOTICE: This email message is for the sole use of the intended
recipient(s) and may contain confidential and privileged information.
Any unauthorized review, use, disclosure or distribution is prohibited.
If you are not the intended recipient, please contact the sender by
reply email and destroy all copies of the original message.
PGP 2048RSA/0x2C5020E9 964C E189 0FF0 8882 2BAB 65E2 6912 1FF2

→ this apparently affects also 3.2.3, I did not see any code changes
from 3.0.12 in the relevant parts.

Ruediger Riediger wrote:

my $MyTickets = new RT::Tickets ($session{‘CurrentUser’});
$MyTickets->LimitMemberOf($Ticket->Id);
I only get #101. Looks like a bug in “RT::tickets::LimitMemberOf”.
Anyone noticed this before and/or got a fix?

What version of RT?

see subject: 3.0.12
I noticed this as RTIR uses the later while RT the first function to
list children.

Some additional info: here is the table extract (table “Links”) from the
DB and some tickets with children that have been merged into 1963:

mysql> select * from Links where LocalBase = 1963;
| id | Base | Target
| Type | LocalTarget | LocalBase | LastUpdatedBy |
LastUpdated | Creator | Created |
| 1090 | fsck.com-rt://sun.com/ticket/1966 |
fsck.com-rt://sun.com/ticket/1963 | MergedInto | 1963 | 1963
| 12 | 2005-04-28 08:18:01 | 12 | 2005-04-28 08:18:01 |
| 1122 | fsck.com-rt://sun.com/ticket/2000 |
fsck.com-rt://sun.com/ticket/1963 | MergedInto | 1963 | 1963
| 12 | 2005-04-29 19:18:10 | 12 | 2005-04-29 19:18:10 |
| 1134 | fsck.com-rt://sun.com/ticket/2030 |
fsck.com-rt://sun.com/ticket/1963 | MergedInto | 1963 | 1963
| 39 | 2005-05-02 12:00:59 | 39 | 2005-05-02 12:00:59 |
| 1135 | fsck.com-rt://sun.com/ticket/2033 |
fsck.com-rt://sun.com/ticket/1963 | MergedInto | 1963 | 1963
| 39 | 2005-05-02 12:01:44 | 39 | 2005-05-02 12:01:44 |
4 rows in set (0.01 sec)

mysql> select * from Links where LocalTarget = 1963;
| id | Base | Target
| Type | LocalTarget | LocalBase | LastUpdatedBy |
LastUpdated | Creator | Created |
| 1080 | fsck.com-rt://sun.com/ticket/1962 |
fsck.com-rt://sun.com/ticket/1963 | MemberOf | 1963 | 1962
| 1 | 2005-04-28 03:46:29 | 1 | 2005-04-28 03:46:29 |
| 1081 | fsck.com-rt://sun.com/ticket/1964 |
fsck.com-rt://sun.com/ticket/1963 | MemberOf | 1963 | 1964
| 1 | 2005-04-28 03:46:43 | 1 | 2005-04-28 03:46:43 |
| 1090 | fsck.com-rt://sun.com/ticket/1966 |
fsck.com-rt://sun.com/ticket/1963 | MergedInto | 1963 | 1963
| 12 | 2005-04-28 08:18:01 | 12 | 2005-04-28 08:18:01 |
| 1091 | fsck.com-rt://sun.com/ticket/1975 |
fsck.com-rt://sun.com/ticket/1963 | MemberOf | 1963 | 1975
| 1 | 2005-04-28 08:48:44 | 1 | 2005-04-28 08:48:44 |
| 1092 | fsck.com-rt://sun.com/ticket/1976 |
fsck.com-rt://sun.com/ticket/1963 | MemberOf | 1963 | 1976
| 1 | 2005-04-28 08:48:59 | 1 | 2005-04-28 08:48:59 |
| 1093 | fsck.com-rt://sun.com/ticket/1977 |
fsck.com-rt://sun.com/ticket/1963 | MemberOf | 1963 | 1977
| 1 | 2005-04-28 09:05:00 | 1 | 2005-04-28 09:05:00 |
| 1122 | fsck.com-rt://sun.com/ticket/2000 |
fsck.com-rt://sun.com/ticket/1963 | MergedInto | 1963 | 1963
| 12 | 2005-04-29 19:18:10 | 12 | 2005-04-29 19:18:10 |
| 1134 | fsck.com-rt://sun.com/ticket/2030 |
fsck.com-rt://sun.com/ticket/1963 | MergedInto | 1963 | 1963
| 39 | 2005-05-02 12:00:59 | 39 | 2005-05-02 12:00:59 |
| 1135 | fsck.com-rt://sun.com/ticket/2033 |
fsck.com-rt://sun.com/ticket/1963 | MergedInto | 1963 | 1963
| 39 | 2005-05-02 12:01:44 | 39 | 2005-05-02 12:01:44 |
9 rows in set (0.00 sec)

And now one ticket that should be empty (but is not):

mysql> select * from Links where LocalBase = 2000;
Empty set (0.00 sec)

mysql> select * from Links where LocalTarget = 2000;
| id | Base | Target
| Type | LocalTarget | LocalBase | LastUpdatedBy |
LastUpdated | Creator | Created |
| 1109 | fsck.com-rt://sun.com/ticket/1999 |
fsck.com-rt://sun.com/ticket/1963 | MemberOf | 2000 | 1999 |
12 | 2005-04-29 19:18:10 | 1 | 2005-04-29 01:42:28 |
| 1110 | fsck.com-rt://sun.com/ticket/2001 |
fsck.com-rt://sun.com/ticket/1963 | MemberOf | 2000 | 2001 |
12 | 2005-04-29 19:18:10 | 1 | 2005-04-29 05:55:17 |
| 1115 | fsck.com-rt://sun.com/ticket/2007 |
fsck.com-rt://sun.com/ticket/1963 | MemberOf | 2000 | 2007 |
12 | 2005-04-29 19:18:10 | 1 | 2005-04-29 07:23:02 |
3 rows in set (0.00 sec)

Shouldn’t be LocalTarget be rather 1963 as well? Looking through the
whole table, I only see “Target” mismatches with “MemberOf”:

mysql> select * from Links where Target LIKE “fsck.com-rt://sun.com/%”
AND Target != concat(“fsck.com-rt://sun.com/ticket/”, LocalTarget);
| id | Base | Target
| Type | LocalTarget | LocalBase | LastUpdatedBy |
LastUpdated | Creator | Created |
| 44 | fsck.com-rt://sun.com/ticket/111 |
fsck.com-rt://sun.com/ticket/223 | MemberOf | 119 | 111
| 39 | 2004-12-09 10:31:01 | 39 | 2004-11-25 08:40:25 |
| 45 | fsck.com-rt://sun.com/ticket/120 |
fsck.com-rt://sun.com/ticket/223 | MemberOf | 119 | 120
| 39 | 2004-12-09 10:31:02 | 39 | 2004-11-25 08:44:26 |
| 60 | fsck.com-rt://sun.com/ticket/145 |
fsck.com-rt://sun.com/ticket/223 | MemberOf | 119 | 145
| 39 | 2004-12-09 10:31:02 | 39 | 2004-11-29 14:57:20 |
| 81 | fsck.com-rt://sun.com/ticket/171 |
fsck.com-rt://sun.com/ticket/223 | MemberOf | 119 | 171
| 39 | 2004-12-09 10:31:02 | 39 | 2004-11-30 12:05:41 |
[…]

Base has the same issues with “MergedInto”:
mysql> select * from Links where Target LIKE “fsck.com-rt://sun.com/%”
AND Base != concat(“fsck.com-rt://sun.com/ticket/”, LocalBase);
| id | Base | Target
| Type | LocalTarget | LocalBase | LastUpdatedBy |
LastUpdated | Creator | Created |
| 5 | fsck.com-rt://sun.com/ticket/10 |
fsck.com-rt://sun.com/ticket/12 | MergedInto | 12 | 12
| 41 | 2004-11-17 18:30:29 | 41 | 2004-11-17 18:30:29 |
| 6 | fsck.com-rt://sun.com/ticket/17 |
fsck.com-rt://sun.com/ticket/16 | MergedInto | 16 | 16
| 41 | 2004-11-17 19:26:19 | 41 | 2004-11-17 19:26:19 |
| 17 | fsck.com-rt://sun.com/ticket/60 |
fsck.com-rt://sun.com/ticket/52 | MergedInto | 52 | 52
| 39 | 2004-11-20 12:43:04 | 39 | 2004-11-20 12:43:04 |
| 18 | fsck.com-rt://sun.com/ticket/77 |
fsck.com-rt://sun.com/ticket/76 | MergedInto | 76 | 76
| 39 | 2004-11-21 23:17:55 | 39 | 2004-11-21 23:17:55 |
| 23 | fsck.com-rt://sun.com/ticket/81 |
fsck.com-rt://sun.com/ticket/79 | MergedInto | 79 | 79
| 39 | 2004-11-22 00:24:17 | 39 | 2004-11-22 00:24:17 |
[…]

Is this rather a problem of the “Ticket->MergeInto” function? Please let
me know, so I can start to fix it at the right place. Don’t want to make
a mess of rewriting it.

In Link_Overlay, a link is created with both “LocalTarget” and “Target”,
however, only the later is updated by “Ticket->MergeInto”:

Link->SUPER::Create( Base => $base->URI,
Target => $target->URI,
LocalBase => $base_id,
LocalTarget => $target_id,
Type => $args{‘Type’} );

Target->MergeInto:

# update all the links that point to that old ticket
my $old_links_to = RT::Links->new($self->CurrentUser);
$old_links_to->Limit(FIELD => 'Target', VALUE => $self->URI);

while (my $link = $old_links_to->Next) {
    if ($link->Base eq $NewTicket->URI) {
        $link->Delete;
    } else {
        $link->SetTarget($NewTicket->URI);
    }

}

(same for Base)

Tickets->Limit seems to use the Local… entry:

my $matchfield = ( $value =~ /^(\d+)$/ ? “LocalTarget” : “Target” );
[…]
my $matchfield = ( $value =~ /^(\d+)$/ ? “LocalBase” : “Base” );

while enumerating the URIs obviously gives the correct results.

Best regards,

Ruediger Riediger

Dr. Ruediger Riediger Sun Microsystems GmbH
NSG - SunCERT Komturstr. 18a
mailto:Ruediger.Riediger@Sun.com D-12099 Berlin
NOTICE: This email message is for the sole use of the intended
recipient(s) and may contain confidential and privileged information.
Any unauthorized review, use, disclosure or distribution is prohibited.
If you are not the intended recipient, please contact the sender by
reply email and destroy all copies of the original message.
PGP 2048RSA/0x2C5020E9 964C E189 0FF0 8882 2BAB 65E2 6912 1FF2

→ this apparently affects also 3.2.3, I did not see any code changes
from 3.0.12 in the relevant parts.

Does 3.4 behave better?

Jesse Vincent wrote:> On Mon, May 09, 2005 at 10:27:16AM +0200, Ruediger Riediger wrote:

→ this apparently affects also 3.2.3, I did not see any code changes
from 3.0.12 in the relevant parts.

Does 3.4 behave better?

I do not have it installed, but will pull the source, configure it, and
compare the relevant parts. Now I know what to check for :wink:

Some update:
The following MySQL commands show the issue:

mysql> SELECT Id,Target,LocalTarget,Type FROM Links WHERE Target LIKE
“fsck.com-rt://sun.com/%” AND Target !=
concat(“fsck.com-rt://sun.com/ticket/”, LocalTarget) ;

mysql> SELECT Id,Base,LocalBase,Type FROM Links WHERE Base LIKE
“fsck.com-rt://sun.com/%” AND Base !=
concat(“fsck.com-rt://sun.com/ticket/”, LocalBase);

→ Obviously, change “sun.com” to your domain prefix from RT::URI.

The following MySQL commands FIX the issue:

mysql> UPDATE Links SET LocalTarget =
replace(Target,‘fsck.com-rt://sun.com/ticket/’,‘’) WHERE Target LIKE
“fsck.com-rt://sun.com/%” AND Target !=
concat(“fsck.com-rt://sun.com/ticket/”, LocalTarget);

mysql> UPDATE Links SET LocalBase =
replace(Base,‘fsck.com-rt://sun.com/ticket/’,‘’) WHERE Base LIKE
“fsck.com-rt://sun.com/%” AND Base !=
concat(“fsck.com-rt://sun.com/ticket/”, LocalBase);

Code change for Ticket::MergeInto still outstanding - I will check 3.4
before making any changes.

Best regards,

Ruediger Riediger

Dr. Ruediger Riediger Sun Microsystems GmbH
NSG - SunCERT Komturstr. 18a
mailto:Ruediger.Riediger@Sun.com D-12099 Berlin
NOTICE: This email message is for the sole use of the intended
recipient(s) and may contain confidential and privileged information.
Any unauthorized review, use, disclosure or distribution is prohibited.
If you are not the intended recipient, please contact the sender by
reply email and destroy all copies of the original message.
PGP 2048RSA/0x2C5020E9 964C E189 0FF0 8882 2BAB 65E2 6912 1FF2

Ruediger Riediger wrote:

Does 3.4 behave better?

RT 3.4 is not affected. It sets both, LocalTarget and Target (same for
Base). Actually, the code change below is already the fix (after
s/$MergeInto/$NewTicket/ :slight_smile:

*** 2894,2905 ****
my $old_links_to = RT::Links->new($self->CurrentUser);
$old_links_to->Limit(FIELD => ‘Target’, VALUE => $self->URI);

  while (my $link = $old_links_to->Next) {

! if ($link->Base eq $NewTicket->URI) {
$link->Delete;
} else {
! $link->SetTarget($NewTicket->URI);
}

  }

— 2716,2740 ----
my $old_links_to = RT::Links->new($self->CurrentUser);
$old_links_to->Limit(FIELD => ‘Target’, VALUE => $self->URI);

  • my %old_seen;
    while (my $link = $old_links_to->Next) {
    

! if (exists $old_seen{$link->Base.“-”.$link->Type}) {
$link->Delete;

  •     }
    
  •     elsif ($link->Base eq $MergeInto->URI) {
    
  •         $link->Delete;
        } else {
    

! # First, make sure the link doesn’t already exist. then
move it over.
! my $tmp = RT::Link->new($RT::SystemUser);
! $tmp->LoadByCols(Base => $link->Base, Type => $link->Type,
LocalTarget => $MergeInto->id);
! if ($tmp->id) {
! $link->Delete;
! } else {
! $link->SetTarget($MergeInto->URI);
! $link->SetLocalTarget($MergeInto->id);
}

  •         $old_seen{$link->Base."-".$link->Type} =1;
    
  •     }
    
    }
    

Best regards,

Ruediger Riediger

Dr. Ruediger Riediger Sun Microsystems GmbH
NSG - SunCERT Komturstr. 18a
mailto:Ruediger.Riediger@Sun.com D-12099 Berlin
NOTICE: This email message is for the sole use of the intended
recipient(s) and may contain confidential and privileged information.
Any unauthorized review, use, disclosure or distribution is prohibited.
If you are not the intended recipient, please contact the sender by
reply email and destroy all copies of the original message.
PGP 2048RSA/0x2C5020E9 964C E189 0FF0 8882 2BAB 65E2 6912 1FF2