]> git.sur5r.net Git - openldap/commitdiff
ITS#5183 - better delete index handling
authorHoward Chu <hyc@openldap.org>
Tue, 20 Nov 2007 12:06:28 +0000 (12:06 +0000)
committerHoward Chu <hyc@openldap.org>
Tue, 20 Nov 2007 12:06:28 +0000 (12:06 +0000)
servers/slapd/back-bdb/modify.c

index 3b852eea91903ebcf6018396e9b0ea296358fdb7..c08e241295ced758eca0daeac45ded766b49f29c 100644 (file)
@@ -43,7 +43,6 @@ int bdb_modify_internal(
        Attribute       *ap;
        int                     glue_attr_delete = 0;
        int                     got_delete;
-       struct berval ix_at;
        AttrInfo *ai;
 
        Debug( LDAP_DEBUG_TRACE, "bdb_modify_internal: 0x%08lx: %s\n",
@@ -90,6 +89,7 @@ int bdb_modify_internal(
        }
 
        for ( ml = modlist; ml != NULL; ml = ml->sml_next ) {
+               struct berval ix_at;
                mod = &ml->sml_mod;
                got_delete = 0;
 
@@ -251,24 +251,57 @@ int bdb_modify_internal(
        /* start with deleting the old index entries */
        for ( ap = save_attrs; ap != NULL; ap = ap->a_next ) {
                if ( ap->a_flags & SLAP_ATTR_IXDEL ) {
-                       rc = bdb_index_values( op, tid, ap->a_desc,
-                               ap->a_nvals,
-                               e->e_id, SLAP_INDEX_DELETE_OP );
-                       if ( rc != LDAP_SUCCESS ) {
-                               attrs_free( e->e_attrs );
-                               e->e_attrs = save_attrs;
-                               Debug( LDAP_DEBUG_ANY,
-                                      "Attribute index delete failure",
-                                      0, 0, 0 );
-                               return rc;
-                       }
+                       struct berval tmp, *vals;
+                       Attribute *a2;
                        ap->a_flags &= ~SLAP_ATTR_IXDEL;
+                       a2 = attr_find( e->e_attrs, ap->a_desc );
+                       if ( a2 ) {
+                               /* need to detect which values were deleted */
+                               int i, j;
+                               struct berval tmp;
+                               j = ap->a_numvals;
+                               for ( i=0; i<j; ) {
+                                       rc = attr_valfind( a2, SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH,
+                                               &ap->a_nvals[i], NULL, op->o_tmpmemctx );
+                                       /* Move deleted values to end of array */
+                                       if ( rc == LDAP_NO_SUCH_ATTRIBUTE ) {
+                                               j--;
+                                               if ( i != j ) {
+                                                       tmp = ap->a_nvals[j];
+                                                       ap->a_nvals[j] = ap->a_nvals[i];
+                                                       ap->a_nvals[i] = tmp;
+                                                       tmp = ap->a_vals[j];
+                                                       ap->a_vals[j] = ap->a_vals[i];
+                                                       ap->a_vals[i] = tmp;
+                                               }
+                                               continue;
+                                       }
+                                       i++;
+                               }
+                               vals = &ap->a_nvals[j];
+                       } else {
+                               /* attribute was completely deleted */
+                               vals = ap->a_nvals;
+                       }
+                       if ( !BER_BVISEMPTY( vals )) {
+                               rc = bdb_index_values( op, tid, ap->a_desc,
+                                       vals, e->e_id, SLAP_INDEX_DELETE_OP );
+                               if ( rc != LDAP_SUCCESS ) {
+                                       attrs_free( e->e_attrs );
+                                       e->e_attrs = save_attrs;
+                                       Debug( LDAP_DEBUG_ANY,
+                                                  "Attribute index delete failure",
+                                                  0, 0, 0 );
+                                       return rc;
+                               }
+                       }
                }
        }
 
        /* add the new index entries */
        for ( ap = e->e_attrs; ap != NULL; ap = ap->a_next ) {
                if (ap->a_flags & SLAP_ATTR_IXADD) {
+                       ap->a_flags &= ~SLAP_ATTR_IXADD;
                        rc = bdb_index_values( op, tid, ap->a_desc,
                                ap->a_nvals,
                                e->e_id, SLAP_INDEX_ADD_OP );
@@ -280,7 +313,6 @@ int bdb_modify_internal(
                                       0, 0, 0 );
                                return rc;
                        }
-                       ap->a_flags &= ~SLAP_ATTR_IXADD;
                }
        }