浏览代码

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.

Noriko Hosoi 16 年之前
父节点
当前提交
abff3feacb
共有 1 个文件被更改,包括 23 次插入19 次删除
  1. 23 19
      ldap/servers/slapd/back-ldbm/index.c

+ 23 - 19
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,