Forum OpenACS Development: Re: Bug in .LRN/openacs group memberships

Posted by Gustaf Neumann on
how comes that the tag is one? Maybe a missing update?

we have:

create or replace function parties_in_tr () returns opaque as '

insert into party_approved_member_map
(party_id, member_id, tag)
(new.party_id, new.party_id, 0);

return new;

end;' language 'plpgsql';

Posted by Tom Jackson on
I have this tag in a very old version of the trigger, so I would guess that there must be another source for the 1. This particular attribute seems ripe for a bug. First, tag is part of a primary key, second it is never used by that name in the functions which use it. But the fact that it is a primary key should be a big flag that this needs to be an fk from (I guess) acs_rels. Then from the rel_id you could figure out the rel_type, knowing the rel_type, you can figure out a lot of other things about the approved member.

The more you look at this code, the more questions arise. What is the purpose of the trigger here? the party is a member of itself. Is that why the rel_id is bogus? Maybe there needs to be an identity_rel. party = member, or we are me?

But I still haven't seen any obvious bug, confusion, but it looks more like a mismatch between new and delete.

Posted by Gustaf Neumann on
Tom wrote
But the fact that it is a primary key should be a big flag that this needs to be an fk from (I guess) acs_rels
Neither 0 or 1 are rel_ids (in acs_rels). So, if there would be a FK for tag, then there should be a different value chosen for the tag in case of the identity (the hypthical "identity-rel" mentioned above, which might be another magic negative value).

The purpose of the trigger is to establish the identity relation (party is approved member of party), which is there for achieving transitive closure (my interpretation, only interesting for transitve memberships).

However, this just source for confusion, not the solution for dave's problem, since we still don't know where the "1"s are from. Are there other dotlrn sites, with

select count(*) from party_approved_member_map where tag = 1;
or is dave's site the only one?

Posted by Tom Jackson on

Okay, here is an idea. Given the imaginary identity relationship which causes the row to be inserted into party_approved_member_map, I don't think that the original statement of the problem matches up this. The party_in_tr is inserting the identity, who knows why it is there, since it could be assumed that every party is that party. But the only way to remove it is to delete the party. The party_del_tr deletes all rows in party_approved_member_map regardless of tag. But the relational segment triggers only delete the rows which have a actual acs_rels.rel_id. So the imaginary tag prevents the removal of this identity row. Obviously this should be necessary. This is the trigger statement that leads me to this idea:

delete from party_approved_member_map
  where party_id = old.segment_id
    and member_id in (select element_id
                      from group_element_index
                      where group_id = old.group_id
                        and rel_type = old.rel_type);

Anyway, in this case, the row is added by a trigger on parties, but 'not removed' by a trigger on rel_segments. This seems correct. But if someone uses a tag which corresponds to a real acs_rel, the identity row may be removed (maybe, not sure, maybe the tag should be changed to the party_id, since we know that id will never be an acs_rels.rel_id, or is there a guarantee that 0 will never be an object_id?)

So my question is: the data exists, but what problem is being caused by it? We never got any actual data rows, so I'm still not sure what would need to be fixed.

On a side note, Dave...the hardest bug to find is one which doesn't exist. But these types of bugs are easier to fix if you consider the possibility! Let's reconsider the actual issue.