AttributeDescription *ad,
struct berval *atname,
BerVarray vals,
+ BerVarray xvals,
ID id,
int opid,
slap_mask_t mask )
{
- int rc, i;
+ int rc, i, j;
const char *text;
DB *db;
- struct berval *keys;
+ struct berval *keys, *xkeys = NULL;
void *mark;
assert( mask );
return LDAP_OTHER;
}
-#if 0 /* No longer needed, our frees are in order so nothing accumulates */
mark = sl_mark(op->o_tmpmemctx);
-#endif
- if( IS_SLAP_INDEX( mask, SLAP_INDEX_PRESENT ) ) {
+ /* For a delete op, make sure we're deleting the entire
+ * attribute (xvals == NULL) before changing the presence
+ * index. xvals is only non-NULL when deleting part of an attribute.
+ */
+ if( IS_SLAP_INDEX( mask, SLAP_INDEX_PRESENT ) && xvals == NULL ) {
rc = bdb_key_change( op->o_bd, db, txn, &presence_key, id, opid );
if( rc ) {
goto done;
atname, vals, &keys, op->o_tmpmemctx );
if( rc == LDAP_SUCCESS && keys != NULL ) {
+ /* xvals is only provided on deletes. Generate the keys for
+ * xvals, representing all of the keys that will exist in
+ * the index when we're done. If we find a delete key that
+ * is in the xkeys, nullify the delete on that key.
+ */
+ if( xvals ) {
+ rc = ad->ad_type->sat_equality->smr_indexer(
+ LDAP_FILTER_EQUALITY, mask,
+ ad->ad_type->sat_syntax,
+ ad->ad_type->sat_equality,
+ atname, xvals, &xkeys,
+ op->o_tmpmemctx );
+
+ for( i=0; keys[i].bv_val; i++ ) {
+ for( j=0; xkeys[j].bv_val != NULL; j++ ) {
+ if( bvmatch( &keys[i], &xkeys[j] ) ) {
+ keys[i].bv_len = 0;
+ }
+ }
+ }
+ }
for( i=0; keys[i].bv_val != NULL; i++ ) {
+ /* ignore nullified keys */
+ if( keys[i].bv_len == 0 ) continue;
rc = bdb_key_change( op->o_bd, db, txn, &keys[i], id, opid );
- if( rc ) {
- ber_bvarray_free_x( keys, op->o_tmpmemctx );
- goto done;
- }
+ if( rc ) break;
+ }
+ if( xkeys ) {
+ ber_bvarray_free_x( xkeys, op->o_tmpmemctx );
+ xkeys = NULL;
}
ber_bvarray_free_x( keys, op->o_tmpmemctx );
+ if( rc ) goto done;
}
rc = LDAP_SUCCESS;
}
atname, vals, &keys, op->o_tmpmemctx );
if( rc == LDAP_SUCCESS && keys != NULL ) {
+ /* nullify duplicate keys */
+ for( i=0; keys[i].bv_val; i++ ) {
+ if( !keys[i].bv_len ) continue;
+ for( j=i+1; keys[j].bv_val; j++ ) {
+ if( bvmatch( &keys[i], &keys[j] ) ) {
+ keys[j].bv_len = 0;
+ break;
+ }
+ }
+ }
+ if( xvals ) {
+ rc = ad->ad_type->sat_equality->smr_indexer(
+ LDAP_FILTER_APPROX, mask,
+ ad->ad_type->sat_syntax,
+ ad->ad_type->sat_approx,
+ atname, xvals, &xkeys,
+ op->o_tmpmemctx );
+
+ for( i=0; keys[i].bv_val; i++ ) {
+ for( j=0; xkeys[j].bv_val != NULL; j++ ) {
+ if( bvmatch( &keys[i], &xkeys[j] ) ) {
+ keys[i].bv_len = 0;
+ }
+ }
+ }
+ }
for( i=0; keys[i].bv_val != NULL; i++ ) {
+ /* ignore nullified keys */
+ if( keys[i].bv_len == 0 ) continue;
rc = bdb_key_change( op->o_bd, db, txn, &keys[i], id, opid );
- if( rc ) {
- ber_bvarray_free_x( keys, op->o_tmpmemctx );
- goto done;
- }
+ if( rc ) break;
+ }
+ if( xkeys ) {
+ ber_bvarray_free_x( xkeys, op->o_tmpmemctx );
+ xkeys = NULL;
}
ber_bvarray_free_x( keys, op->o_tmpmemctx );
+ if( rc ) goto done;
}
rc = LDAP_SUCCESS;
atname, vals, &keys, op->o_tmpmemctx );
if( rc == LDAP_SUCCESS && keys != NULL ) {
+ /* nullify duplicate keys */
+ for( i=0; keys[i].bv_val; i++ ) {
+ if( !keys[i].bv_len ) continue;
+ for( j=i+1; keys[j].bv_val; j++ ) {
+ if( bvmatch( &keys[i], &keys[j] ) ) {
+ keys[j].bv_len = 0;
+ break;
+ }
+ }
+ }
+ if( xvals ) {
+ rc = ad->ad_type->sat_equality->smr_indexer(
+ LDAP_FILTER_SUBSTRINGS, mask,
+ ad->ad_type->sat_syntax,
+ ad->ad_type->sat_substr,
+ atname, xvals, &xkeys,
+ op->o_tmpmemctx );
+
+ for( i=0; keys[i].bv_val; i++ ) {
+ for( j=0; xkeys[j].bv_val != NULL; j++ ) {
+ if( bvmatch( &keys[i], &xkeys[j] ) ) {
+ keys[i].bv_len = 0;
+ }
+ }
+ }
+ }
for( i=0; keys[i].bv_val != NULL; i++ ) {
+ /* ignore nullified keys */
+ if ( keys[i].bv_len == 0 ) continue;
bdb_key_change( op->o_bd, db, txn, &keys[i], id, opid );
- if( rc ) {
- ber_bvarray_free_x( keys, op->o_tmpmemctx );
- goto done;
- }
+ if( rc ) break;
+ }
+ if( xkeys ) {
+ ber_bvarray_free_x( xkeys, op->o_tmpmemctx );
+ xkeys = NULL;
}
ber_bvarray_free_x( keys, op->o_tmpmemctx );
+ if( rc ) goto done;
}
rc = LDAP_SUCCESS;
}
done:
-#if 0
sl_release( mark, op->o_tmpmemctx );
-#endif
return rc;
}
AttributeType *type,
struct berval *tags,
BerVarray vals,
+ BerVarray xvals,
ID id,
int opid )
{
/* recurse */
rc = index_at_values( op, txn, NULL,
type->sat_sup, tags,
- vals, id, opid );
+ vals, xvals, id, opid );
if( rc ) return rc;
}
if( mask ) {
rc = indexer( op, txn, ad, &type->sat_cname,
- vals, id, opid,
+ vals, xvals, id, opid,
mask );
if( rc ) return rc;
if( mask ) {
rc = indexer( op, txn, desc, &desc->ad_cname,
- vals, id, opid,
+ vals, xvals, id, opid,
mask );
if( rc ) {
DB_TXN *txn,
AttributeDescription *desc,
BerVarray vals,
+ BerVarray xvals,
ID id,
int opid )
{
rc = index_at_values( op, txn, desc,
desc->ad_type, &desc->ad_tags,
- vals, id, opid );
+ vals, xvals, id, opid );
return rc;
}
/* add each attribute to the indexes */
for ( ; ap != NULL; ap = ap->a_next ) {
rc = bdb_index_values( op, txn, ap->a_desc,
- ap->a_nvals, e->e_id, opid );
+ ap->a_nvals, NULL, e->e_id, opid );
if( rc != LDAP_SUCCESS ) {
#ifdef NEW_LOGGING