https://bugzilla.redhat.com/show_bug.cgi?id=506786 There was a not-working case found in my previous proposal. The problem is if these attribute value pairs exist in an entry: mail: abc mail;en: abc mail;fr: xyzremoving mail=abc or mail;en=abc, should not remove =abc from the mail.db#. My previous fix worked only when removing "mail;en=abc", but not when removing "mail=abc".
[Problem Description]When adding a value to an attribute with subtype indexed on equality and then
deleting this attribute subtype the index is not maintained correctly which results in wrong search results afterwards. After stopping the server andreindexing with db2index everything works correctly again. The unindexed and
substring searches do not seem to be concerned. [Fix Description] When there are identical attribute value pairs except subtypes exist in an entry, if one of the pairs are deleted, it should not affect the index the attribute value is the key. e.g., mail: abc mail;en: abc mail;fr: xyz removing mail=abc or mail;en=abc, should not remove =abc from the mail.db#. This fix uses the value array evals to determine if the equality key in the index should be deleted or not. The value array evals stores the values of the attribute in the entry after the deletion is done. If evals is empty, it means the to-be-deleted attribute value pair is the only pair in the entry. Thus, the equality key can be removed fom the index. If evals has values, then the to-be-deleted attribute (curr_attr, which was retrieved from the old entry) value needs to be checked if it's in evals or not. If it is in evals, the equality key is still used by other pair(s). So, leave it. Otherwise, the key can be removed. In the above example, let's assume removing mail=abc. evals holds {"abc", "xyz"}. curr_attr abc is in evals, thus =abc will not be removed.
From abff3feacb218a7bb65a358dce2e9c90a2f185b1 Mon Sep 17 00:00:00 2001 From: Noriko Hosoi <nhosoi@xxxxxxxxxx> Date: Mon, 10 Aug 2009 17:36:36 -0700 Subject: [PATCH] 506786 Index maintenance mechanism causes wrong search results when modifying attributes with subtypes When there are identical attribute value pairs except subtypes exist in an entry, if one of the pairs are deleted, it should not affect the index the attribute value is the key. e.g., mail: abc mail;en: abc mail;fr: xyz removing mail=abc or mail;en=abc, should not remove =abc from the mail.db#. This fix uses the value array evals to determine if the equality key in the index should be deleted or not. The value array evals stores the values of the attribute in the entry after the deletion is done. If evals is empty, it means the to-be-deleted attribute value pair is the only pair in the entry. Thus, the equality key can be removed fom the index. If evals has values, then the to-be-deleted attribute (curr_attr, which was retrieved from the old entry) value needs to be checked if it's in evals or not. If it is in evals, the equality key is still used by other pair(s). So, leave it. Otherwise, the key can be removed. In the above example, let's assume removing mail=abc. evals holds {"abc", "xyz"}. curr_attr abc is in evals, thus =abc will not be removed. --- ldap/servers/slapd/back-ldbm/index.c | 42 ++++++++++++++++++--------------- 1 files changed, 23 insertions(+), 19 deletions(-) diff --git a/ldap/servers/slapd/back-ldbm/index.c b/ldap/servers/slapd/back-ldbm/index.c index 3c639c2..c4b905c 100644 --- a/ldap/servers/slapd/back-ldbm/index.c +++ b/ldap/servers/slapd/back-ldbm/index.c @@ -641,30 +641,34 @@ index_add_mods( * for this attribute?) */ if (evals == NULL || evals[0] == NULL) { - flags = BE_INDEX_DEL|BE_INDEX_PRESENCE; + /* The new entry newe does not have the attribute at all + * including the one with subtypes. Thus it's safe to + * remove the presence and equality index. + */ + flags = BE_INDEX_DEL|BE_INDEX_PRESENCE|BE_INDEX_EQUALITY; } else { flags = BE_INDEX_DEL; - } - /* If the same value doesn't exist in a subtype, set - * BE_INDEX_EQUALITY flag so the equality index is - * removed. - */ - slapi_entry_attr_find( newe->ep_entry, mods[i]->mod_type, &curr_attr); - if (curr_attr) { - for (j = 0; mods_valueArray[j] != NULL; j++ ) { - if ( valuearray_find(curr_attr, evals, mods_valueArray[j]) == -1 ) { - if (!(flags & BE_INDEX_EQUALITY)) { - flags |= BE_INDEX_EQUALITY; + /* If the same value doesn't exist in a subtype, set + * BE_INDEX_EQUALITY flag so the equality index is + * removed. + */ + slapi_entry_attr_find( olde->ep_entry, mods[i]->mod_type, &curr_attr ); + if (curr_attr) { + int found = 0; + for (j = 0; mods_valueArray[j] != NULL; j++ ) { + if ( valuearray_find(curr_attr, evals, mods_valueArray[j]) > -1 ) { + found = 1; } } - } - } else { - /* If we didn't find the attribute in the new - * entry, we should remove the equality index. */ - if (!(flags & BE_INDEX_EQUALITY)) { - flags |= BE_INDEX_EQUALITY; - } + /* + * to-be-deleted curr_attr does not exist in the + * new value set evals. So, we can remove it. + */ + if (!found && !(flags & BE_INDEX_EQUALITY)) { + flags |= BE_INDEX_EQUALITY; + } + } } rc = index_addordel_values_sv( be, basetype, -- 1.6.2.5
Attachment:
smime.p7s
Description: S/MIME Cryptographic Signature
-- 389-devel mailing list 389-devel@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/fedora-directory-devel