125450Speter/* $NetBSD$ */ 250476Speter 325450Speter/* index.c - routines for dealing with attribute indexes */ 425450Speter/* OpenLDAP: pkg/ldap/servers/slapd/back-bdb/index.c,v 1.61.2.9 2010/04/13 20:23:25 kurt Exp */ 525450Speter/* This work is part of OpenLDAP Software <http://www.openldap.org/>. 625450Speter * 725450Speter * Copyright 2000-2010 The OpenLDAP Foundation. 825450Speter * All rights reserved. 925450Speter * 1025450Speter * Redistribution and use in source and binary forms, with or without 1125450Speter * modification, are permitted only as authorized by the OpenLDAP 1225450Speter * Public License. 1325450Speter * 1425450Speter * A copy of this license is available in the file LICENSE in the 1525450Speter * top-level directory of the distribution or, alternatively, at 1625450Speter * <http://www.OpenLDAP.org/license.html>. 1725450Speter */ 1825450Speter 1925450Speter#include "portable.h" 2025450Speter 2125450Speter#include <stdio.h> 2225450Speter 2325450Speter#include <ac/string.h> 2425450Speter#include <ac/socket.h> 2525450Speter 2625450Speter#include "slap.h" 2725450Speter#include "back-bdb.h" 2825450Speter#include "lutil_hash.h" 2925450Speter 3025450Speterstatic char presence_keyval[] = {0,0}; 3125450Speterstatic struct berval presence_key = BER_BVC(presence_keyval); 3225450Speter 3325450SpeterAttrInfo *bdb_index_mask( 3425450Speter Backend *be, 3525450Speter AttributeDescription *desc, 3625450Speter struct berval *atname ) 3725450Speter{ 3825450Speter AttributeType *at; 3925450Speter AttrInfo *ai = bdb_attr_mask( be->be_private, desc ); 4025450Speter 4125450Speter if( ai ) { 4225450Speter *atname = desc->ad_cname; 4325450Speter return ai; 4425450Speter } 4525450Speter 4625450Speter /* If there is a tagging option, did we ever index the base 4725450Speter * type? If so, check for mask, otherwise it's not there. 4825450Speter */ 4925450Speter if( slap_ad_is_tagged( desc ) && desc != desc->ad_type->sat_ad ) { 5025450Speter /* has tagging option */ 5125450Speter ai = bdb_attr_mask( be->be_private, desc->ad_type->sat_ad ); 5225450Speter 5325450Speter if ( ai && !( ai->ai_indexmask & SLAP_INDEX_NOTAGS ) ) { 5425450Speter *atname = desc->ad_type->sat_cname; 5525450Speter return ai; 5625450Speter } 5725450Speter } 5825450Speter 5925450Speter /* see if supertype defined mask for its subtypes */ 6025450Speter for( at = desc->ad_type; at != NULL ; at = at->sat_sup ) { 6125450Speter /* If no AD, we've never indexed this type */ 6225450Speter if ( !at->sat_ad ) continue; 6325450Speter 6425450Speter ai = bdb_attr_mask( be->be_private, at->sat_ad ); 6525450Speter 6625450Speter if ( ai && !( ai->ai_indexmask & SLAP_INDEX_NOSUBTYPES ) ) { 6725450Speter *atname = at->sat_cname; 6825450Speter return ai; 6925450Speter } 7025450Speter } 7125450Speter 7225450Speter return 0; 7325450Speter} 7425450Speter 7525450Speter/* This function is only called when evaluating search filters. 7625450Speter */ 7725450Speterint bdb_index_param( 7825450Speter Backend *be, 7925450Speter AttributeDescription *desc, 8025450Speter int ftype, 8125450Speter DB **dbp, 8225450Speter slap_mask_t *maskp, 8325450Speter struct berval *prefixp ) 8425450Speter{ 8525450Speter AttrInfo *ai; 8625450Speter int rc; 8725450Speter slap_mask_t mask, type = 0; 8825450Speter DB *db; 8925450Speter 9025450Speter ai = bdb_index_mask( be, desc, prefixp ); 9125450Speter 9295005Simp if ( !ai ) { 9395005Simp#ifdef BDB_MONITOR_IDX 94114164Ssam switch ( ftype ) { 9595005Simp case LDAP_FILTER_PRESENT: 9695005Simp type = SLAP_INDEX_PRESENT; 9795005Simp break; 9895005Simp case LDAP_FILTER_APPROX: 9925450Speter type = SLAP_INDEX_APPROX; 10095005Simp break; 10195005Simp case LDAP_FILTER_EQUALITY: 10295005Simp type = SLAP_INDEX_EQUALITY; 10395005Simp break; 10477385Sphk case LDAP_FILTER_SUBSTRINGS: 105138593Ssam type = SLAP_INDEX_SUBSTR; 106139494Ssam break; 10725450Speter default: 10825450Speter return LDAP_INAPPROPRIATE_MATCHING; 10925450Speter } 11025450Speter bdb_monitor_idx_add( be->be_private, desc, type ); 11125450Speter#endif /* BDB_MONITOR_IDX */ 11225450Speter 11325450Speter return LDAP_INAPPROPRIATE_MATCHING; 11425450Speter } 11525450Speter mask = ai->ai_indexmask; 11625450Speter 11725450Speter rc = bdb_db_cache( be, prefixp, &db ); 11825450Speter 11925450Speter if( rc != LDAP_SUCCESS ) { 12025450Speter return rc; 12125450Speter } 12225450Speter 12325450Speter switch( ftype ) { 12425450Speter case LDAP_FILTER_PRESENT: 12525450Speter type = SLAP_INDEX_PRESENT; 12625450Speter if( IS_SLAP_INDEX( mask, SLAP_INDEX_PRESENT ) ) { 12725450Speter *prefixp = presence_key; 12825450Speter goto done; 12925450Speter } 13025450Speter break; 13125450Speter 13225450Speter case LDAP_FILTER_APPROX: 13325450Speter type = SLAP_INDEX_APPROX; 13425450Speter if ( desc->ad_type->sat_approx ) { 13577385Sphk if( IS_SLAP_INDEX( mask, SLAP_INDEX_APPROX ) ) { 13625450Speter goto done; 13725450Speter } 13825450Speter break; 13977385Sphk } 14025450Speter 14125450Speter /* Use EQUALITY rule and index for approximate match */ 14225450Speter /* fall thru */ 14377385Sphk 14477385Sphk case LDAP_FILTER_EQUALITY: 14525450Speter type = SLAP_INDEX_EQUALITY; 14677385Sphk if( IS_SLAP_INDEX( mask, SLAP_INDEX_EQUALITY ) ) { 14725450Speter goto done; 14825450Speter } 14925450Speter break; 15025450Speter 15125450Speter case LDAP_FILTER_SUBSTRINGS: 15225450Speter type = SLAP_INDEX_SUBSTR; 15325450Speter if( IS_SLAP_INDEX( mask, SLAP_INDEX_SUBSTR ) ) { 15425450Speter goto done; 15525450Speter } 15625450Speter break; 15725450Speter 15825450Speter default: 15925450Speter return LDAP_OTHER; 16025450Speter } 16125450Speter 162114232Sharti#ifdef BDB_MONITOR_IDX 163114232Sharti bdb_monitor_idx_add( be->be_private, desc, type ); 164114232Sharti#endif /* BDB_MONITOR_IDX */ 165114232Sharti 166114232Sharti return LDAP_INAPPROPRIATE_MATCHING; 167114232Sharti 168114232Shartidone: 169114232Sharti *dbp = db; 17077217Sphk *maskp = mask; 17177217Sphk return LDAP_SUCCESS; 17277217Sphk} 17377217Sphk 17477217Sphkstatic int indexer( 17577217Sphk Operation *op, 17677217Sphk DB_TXN *txn, 17725450Speter AttributeDescription *ad, 17885853Syar struct berval *atname, 17925450Speter BerVarray vals, 18025450Speter ID id, 18177385Sphk int opid, 18277385Sphk slap_mask_t mask ) 18325450Speter{ 18477385Sphk int rc, i; 18577385Sphk DB *db; 18677385Sphk struct berval *keys; 18725450Speter 18825450Speter assert( mask != 0 ); 18925450Speter 19025450Speter rc = bdb_db_cache( op->o_bd, atname, &db ); 19125450Speter 19225450Speter if ( rc != LDAP_SUCCESS ) { 193138593Ssam Debug( LDAP_DEBUG_ANY, 19495005Simp "bdb_index_read: Could not open DB %s\n", 19525450Speter atname->bv_val, 0, 0 ); 19625450Speter return LDAP_OTHER; 19725450Speter } 19825450Speter 19925450Speter if( IS_SLAP_INDEX( mask, SLAP_INDEX_PRESENT ) ) { 20025450Speter rc = bdb_key_change( op->o_bd, db, txn, &presence_key, id, opid ); 20125450Speter if( rc ) { 20225450Speter goto done; 20325450Speter } 20425450Speter } 20525450Speter 20625450Speter if( IS_SLAP_INDEX( mask, SLAP_INDEX_EQUALITY ) ) { 20725450Speter rc = ad->ad_type->sat_equality->smr_indexer( 20825450Speter LDAP_FILTER_EQUALITY, 20925450Speter mask, 21025450Speter ad->ad_type->sat_syntax, 21125450Speter ad->ad_type->sat_equality, 21225450Speter atname, vals, &keys, op->o_tmpmemctx ); 21325450Speter 21425450Speter if( rc == LDAP_SUCCESS && keys != NULL ) { 21525450Speter for( i=0; keys[i].bv_val != NULL; i++ ) { 21625450Speter rc = bdb_key_change( op->o_bd, db, txn, &keys[i], id, opid ); 21725450Speter if( rc ) { 21825450Speter ber_bvarray_free_x( keys, op->o_tmpmemctx ); 21925450Speter goto done; 22025450Speter } 22125450Speter } 22225450Speter ber_bvarray_free_x( keys, op->o_tmpmemctx ); 22325450Speter } 22425450Speter rc = LDAP_SUCCESS; 22525450Speter } 22625450Speter 22725450Speter if( IS_SLAP_INDEX( mask, SLAP_INDEX_APPROX ) ) { 22825450Speter rc = ad->ad_type->sat_approx->smr_indexer( 22925450Speter LDAP_FILTER_APPROX, 23025450Speter mask, 23125450Speter ad->ad_type->sat_syntax, 232114164Ssam ad->ad_type->sat_approx, 23325450Speter atname, vals, &keys, op->o_tmpmemctx ); 23425450Speter 235138593Ssam if( rc == LDAP_SUCCESS && keys != NULL ) { 23695005Simp for( i=0; keys[i].bv_val != NULL; i++ ) { 23725450Speter rc = bdb_key_change( op->o_bd, db, txn, &keys[i], id, opid ); 23825450Speter if( rc ) { 23925450Speter ber_bvarray_free_x( keys, op->o_tmpmemctx ); 24025450Speter goto done; 24125450Speter } 242138593Ssam } 24395005Simp ber_bvarray_free_x( keys, op->o_tmpmemctx ); 24425450Speter } 24525450Speter 24625450Speter rc = LDAP_SUCCESS; 24725450Speter } 24825450Speter 24925450Speter if( IS_SLAP_INDEX( mask, SLAP_INDEX_SUBSTR ) ) { 25095005Simp rc = ad->ad_type->sat_substr->smr_indexer( 25125450Speter LDAP_FILTER_SUBSTRINGS, 25225450Speter mask, 25325450Speter ad->ad_type->sat_syntax, 25425450Speter ad->ad_type->sat_substr, 25525450Speter atname, vals, &keys, op->o_tmpmemctx ); 25625450Speter 25725450Speter if( rc == LDAP_SUCCESS && keys != NULL ) { 25825450Speter for( i=0; keys[i].bv_val != NULL; i++ ) { 25925450Speter rc = bdb_key_change( op->o_bd, db, txn, &keys[i], id, opid ); 26025450Speter if( rc ) { 26125450Speter ber_bvarray_free_x( keys, op->o_tmpmemctx ); 26225450Speter goto done; 26325450Speter } 26425450Speter } 26525450Speter ber_bvarray_free_x( keys, op->o_tmpmemctx ); 26625450Speter } 26725450Speter 26825450Speter rc = LDAP_SUCCESS; 26925450Speter } 27025450Speter 27125450Speterdone: 27225450Speter switch( rc ) { 27325450Speter /* The callers all know how to deal with these results */ 27425450Speter case 0: 27525450Speter case DB_LOCK_DEADLOCK: 27625450Speter case DB_LOCK_NOTGRANTED: 27725450Speter break; 27825450Speter /* Anything else is bad news */ 27925450Speter default: 28025450Speter rc = LDAP_OTHER; 28125450Speter } 28225450Speter return rc; 28325450Speter} 28425450Speter 28525450Speterstatic int index_at_values( 28625450Speter Operation *op, 28725450Speter DB_TXN *txn, 28825450Speter AttributeDescription *ad, 28925450Speter AttributeType *type, 290114164Ssam struct berval *tags, 29125450Speter BerVarray vals, 29225450Speter ID id, 293114164Ssam int opid ) 294138593Ssam{ 295114164Ssam int rc; 296114164Ssam slap_mask_t mask = 0; 297114164Ssam int ixop = opid; 298114164Ssam AttrInfo *ai = NULL; 299114164Ssam 300114164Ssam if ( opid == BDB_INDEX_UPDATE_OP ) 301114164Ssam ixop = SLAP_INDEX_ADD_OP; 302114164Ssam 303114164Ssam if( type->sat_sup ) { 304114164Ssam /* recurse */ 305114164Ssam rc = index_at_values( op, txn, NULL, 306114164Ssam type->sat_sup, tags, 307114164Ssam vals, id, opid ); 308114164Ssam 309114164Ssam if( rc ) return rc; 310114164Ssam } 311114164Ssam 312114164Ssam /* If this type has no AD, we've never used it before */ 313114164Ssam if( type->sat_ad ) { 314114164Ssam ai = bdb_attr_mask( op->o_bd->be_private, type->sat_ad ); 315114164Ssam if ( ai ) { 316114164Ssam#ifdef LDAP_COMP_MATCH 317114164Ssam /* component indexing */ 318114164Ssam if ( ai->ai_cr ) { 319114164Ssam ComponentReference *cr; 320114164Ssam for( cr = ai->ai_cr ; cr ; cr = cr->cr_next ) { 321114164Ssam rc = indexer( op, txn, cr->cr_ad, &type->sat_cname, 322114164Ssam cr->cr_nvals, id, ixop, 323114164Ssam cr->cr_indexmask ); 324114164Ssam } 325114164Ssam } 326114164Ssam#endif 327114164Ssam ad = type->sat_ad; 328124560Ssam /* If we're updating the index, just set the new bits that aren't 329114164Ssam * already in the old mask. 330114164Ssam */ 331114164Ssam if ( opid == BDB_INDEX_UPDATE_OP ) 332114164Ssam mask = ai->ai_newmask & ~ai->ai_indexmask; 333114164Ssam else 33425450Speter /* For regular updates, if there is a newmask use it. Otherwise 33525450Speter * just use the old mask. 33625450Speter */ 33725450Speter mask = ai->ai_newmask ? ai->ai_newmask : ai->ai_indexmask; 33825450Speter if( mask ) { 33925450Speter rc = indexer( op, txn, ad, &type->sat_cname, 34025450Speter vals, id, ixop, mask ); 34125450Speter 34225450Speter if( rc ) return rc; 34325450Speter } 34425450Speter } 34525450Speter } 34625450Speter 34725450Speter if( tags->bv_len ) { 34825450Speter AttributeDescription *desc; 34925450Speter 35025450Speter desc = ad_find_tags( type, tags ); 35125450Speter if( desc ) { 35225450Speter ai = bdb_attr_mask( op->o_bd->be_private, desc ); 35325450Speter 35425450Speter if( ai ) { 35525450Speter if ( opid == BDB_INDEX_UPDATE_OP ) 35625450Speter mask = ai->ai_newmask & ~ai->ai_indexmask; 35725450Speter else 35825450Speter mask = ai->ai_newmask ? ai->ai_newmask : ai->ai_indexmask; 35925450Speter if ( mask ) { 36025450Speter rc = indexer( op, txn, desc, &desc->ad_cname, 36125450Speter vals, id, ixop, mask ); 36225450Speter 36325450Speter if( rc ) { 36425450Speter return rc; 36525450Speter } 36625450Speter } 36725450Speter } 36877217Sphk } 36977217Sphk } 37077217Sphk 37177217Sphk return LDAP_SUCCESS; 37277217Sphk} 37377217Sphk 37477217Sphkint bdb_index_values( 37577217Sphk Operation *op, 37677217Sphk DB_TXN *txn, 377114164Ssam AttributeDescription *desc, 378114164Ssam BerVarray vals, 379114164Ssam ID id, 380116820Ssam int opid ) 381116820Ssam{ 382116820Ssam int rc; 383114232Sharti 384114232Sharti /* Never index ID 0 */ 385114232Sharti if ( id == 0 ) 386114232Sharti return 0; 387114232Sharti 388114232Sharti rc = index_at_values( op, txn, desc, 389114232Sharti desc->ad_type, &desc->ad_tags, 390114232Sharti vals, id, opid ); 391114232Sharti 39225450Speter return rc; 39325450Speter} 39425450Speter 39525450Speter/* Get the list of which indices apply to this attr */ 39625450Speterint 39725450Speterbdb_index_recset( 39825450Speter struct bdb_info *bdb, 39925450Speter Attribute *a, 40025450Speter AttributeType *type, 40125450Speter struct berval *tags, 40225450Speter IndexRec *ir ) 40325450Speter{ 40425450Speter int rc, slot; 40525450Speter AttrList *al; 40625450Speter 40725450Speter if( type->sat_sup ) { 40825450Speter /* recurse */ 40925450Speter rc = bdb_index_recset( bdb, a, type->sat_sup, tags, ir ); 410114164Ssam if( rc ) return rc; 411114164Ssam } 412114164Ssam /* If this type has no AD, we've never used it before */ 413116820Ssam if( type->sat_ad ) { 41425450Speter slot = bdb_attr_slot( bdb, type->sat_ad, NULL ); 41525450Speter if ( slot >= 0 ) { 41625450Speter ir[slot].ai = bdb->bi_attrs[slot]; 41725450Speter al = ch_malloc( sizeof( AttrList )); 41825450Speter al->attr = a; 41925450Speter al->next = ir[slot].attrs; 42025450Speter ir[slot].attrs = al; 42125450Speter } 42225450Speter } 42325450Speter if( tags->bv_len ) { 42425450Speter AttributeDescription *desc; 42525450Speter 42625450Speter desc = ad_find_tags( type, tags ); 42725450Speter if( desc ) { 42877217Sphk slot = bdb_attr_slot( bdb, desc, NULL ); 42925450Speter if ( slot >= 0 ) { 43025450Speter ir[slot].ai = bdb->bi_attrs[slot]; 431114164Ssam al = ch_malloc( sizeof( AttrList )); 432114164Ssam al->attr = a; 433114164Ssam al->next = ir[slot].attrs; 43425450Speter ir[slot].attrs = al; 43525450Speter } 43625450Speter } 43725450Speter } 43825450Speter return LDAP_SUCCESS; 43925450Speter} 44025450Speter 44125450Speter/* Apply the indices for the recset */ 44225450Speterint bdb_index_recrun( 44325450Speter Operation *op, 44425450Speter struct bdb_info *bdb, 44577217Sphk IndexRec *ir0, 44625450Speter ID id, 44725450Speter int base ) 448114164Ssam{ 449114164Ssam IndexRec *ir; 450114164Ssam AttrList *al; 45125450Speter int i, rc = 0; 45225450Speter 45325450Speter /* Never index ID 0 */ 45425450Speter if ( id == 0 ) 45525450Speter return 0; 45625450Speter 45725450Speter for (i=base; i<bdb->bi_nattrs; i+=slap_tool_thread_max) { 45825450Speter ir = ir0 + i; 45925450Speter if ( !ir->ai ) continue; 46025450Speter while (( al = ir->attrs )) { 46125450Speter ir->attrs = al->next; 46277217Sphk rc = indexer( op, NULL, ir->ai->ai_desc, 46325450Speter &ir->ai->ai_desc->ad_type->sat_cname, 46425450Speter al->attr->a_nvals, id, SLAP_INDEX_ADD_OP, 465114164Ssam ir->ai->ai_indexmask ); 466114164Ssam free( al ); 467114164Ssam if ( rc ) break; 46825450Speter } 46977217Sphk } 47077217Sphk return rc; 47177217Sphk} 47277217Sphk 47377217Sphkint 47477217Sphkbdb_index_entry( 47577217Sphk Operation *op, 47677217Sphk DB_TXN *txn, 47777217Sphk int opid, 47877217Sphk Entry *e ) 47977217Sphk{ 48077217Sphk int rc; 48177217Sphk Attribute *ap = e->e_attrs; 482114164Ssam#if 0 /* ifdef LDAP_COMP_MATCH */ 483114164Ssam ComponentReference *cr_list = NULL; 484116820Ssam ComponentReference *cr = NULL, *dupped_cr = NULL; 485114164Ssam void* decoded_comp; 486114164Ssam ComponentSyntaxInfo* csi_attr; 48777217Sphk Syntax* syn; 488114232Sharti AttributeType* at; 489114232Sharti int i, num_attr; 490114232Sharti void* mem_op; 491114232Sharti struct berval value = {0}; 492114232Sharti#endif 493114232Sharti 494114232Sharti /* Never index ID 0 */ 495114232Sharti if ( e->e_id == 0 ) 496114232Sharti return 0; 497114232Sharti 498114232Sharti Debug( LDAP_DEBUG_TRACE, "=> index_entry_%s( %ld, \"%s\" )\n", 499114232Sharti opid == SLAP_INDEX_DELETE_OP ? "del" : "add", 500114232Sharti (long) e->e_id, e->e_dn ); 501114232Sharti 502114232Sharti /* add each attribute to the indexes */ 503114232Sharti for ( ; ap != NULL; ap = ap->a_next ) { 504114232Sharti#if 0 /* ifdef LDAP_COMP_MATCH */ 50525450Speter AttrInfo *ai; 50625450Speter /* see if attribute has components to be indexed */ 50725450Speter ai = bdb_attr_mask( op->o_bd->be_private, ap->a_desc->ad_type->sat_ad ); 50895005Simp if ( !ai ) continue; 50925450Speter cr_list = ai->ai_cr; 51025450Speter if ( attr_converter && cr_list ) { 51125450Speter syn = ap->a_desc->ad_type->sat_syntax; 51225450Speter ap->a_comp_data = op->o_tmpalloc( sizeof( ComponentData ), op->o_tmpmemctx ); 51325450Speter /* Memory chunk(nibble) pre-allocation for decoders */ 51425450Speter mem_op = nibble_mem_allocator ( 1024*16, 1024*4 ); 51525450Speter ap->a_comp_data->cd_mem_op = mem_op; 51625450Speter for( cr = cr_list ; cr ; cr = cr->cr_next ) { 51725450Speter /* count how many values in an attribute */ 51825450Speter for( num_attr=0; ap->a_vals[num_attr].bv_val != NULL; num_attr++ ); 51925450Speter num_attr++; 52025450Speter cr->cr_nvals = (BerVarray)op->o_tmpalloc( sizeof( struct berval )*num_attr, op->o_tmpmemctx ); 52125450Speter for( i=0; ap->a_vals[i].bv_val != NULL; i++ ) { 52225450Speter /* decoding attribute value */ 52325450Speter decoded_comp = attr_converter ( ap, syn, &ap->a_vals[i] ); 52425450Speter if ( !decoded_comp ) 52525450Speter return LDAP_DECODING_ERROR; 52625450Speter /* extracting the referenced component */ 52725450Speter dupped_cr = dup_comp_ref( op, cr ); 528114164Ssam csi_attr = ((ComponentSyntaxInfo*)decoded_comp)->csi_comp_desc->cd_extract_i( mem_op, dupped_cr, decoded_comp ); 52925450Speter if ( !csi_attr ) 53025450Speter return LDAP_DECODING_ERROR; 53125450Speter cr->cr_asn_type_id = csi_attr->csi_comp_desc->cd_type_id; 532114164Ssam cr->cr_ad = (AttributeDescription*)get_component_description ( cr->cr_asn_type_id ); 533114164Ssam if ( !cr->cr_ad ) 534114164Ssam return LDAP_INVALID_SYNTAX; 535114164Ssam at = cr->cr_ad->ad_type; 536114164Ssam /* encoding the value of component in GSER */ 537114164Ssam rc = component_encoder( mem_op, csi_attr, &value ); 538114164Ssam if ( rc != LDAP_SUCCESS ) 539114164Ssam return LDAP_ENCODING_ERROR; 540114164Ssam /* Normalize the encoded component values */ 541114164Ssam if ( at->sat_equality && at->sat_equality->smr_normalize ) { 542114164Ssam rc = at->sat_equality->smr_normalize ( 543114164Ssam SLAP_MR_VALUE_OF_ATTRIBUTE_SYNTAX, 544114164Ssam at->sat_syntax, at->sat_equality, 545114164Ssam &value, &cr->cr_nvals[i], op->o_tmpmemctx ); 546114164Ssam } else { 547114164Ssam cr->cr_nvals[i] = value; 548114164Ssam } 549114164Ssam } 550114164Ssam /* The end of BerVarray */ 551114164Ssam cr->cr_nvals[num_attr-1].bv_val = NULL; 552114164Ssam cr->cr_nvals[num_attr-1].bv_len = 0; 553114164Ssam } 554114164Ssam op->o_tmpfree( ap->a_comp_data, op->o_tmpmemctx ); 55595005Simp nibble_mem_free ( mem_op ); 55625450Speter ap->a_comp_data = NULL; 55725450Speter } 55825450Speter#endif 55925450Speter rc = bdb_index_values( op, txn, ap->a_desc, 56025450Speter ap->a_nvals, e->e_id, opid ); 56125450Speter 56225450Speter if( rc != LDAP_SUCCESS ) { 56325450Speter Debug( LDAP_DEBUG_TRACE, 56425450Speter "<= index_entry_%s( %ld, \"%s\" ) failure\n", 56525450Speter opid == SLAP_INDEX_ADD_OP ? "add" : "del", 56625450Speter (long) e->e_id, e->e_dn ); 56725450Speter return rc; 56825450Speter } 56925450Speter } 57025450Speter 57125450Speter Debug( LDAP_DEBUG_TRACE, "<= index_entry_%s( %ld, \"%s\" ) success\n", 57225450Speter opid == SLAP_INDEX_DELETE_OP ? "del" : "add", 57325450Speter (long) e->e_id, e->e_dn ); 57425450Speter 57525450Speter return LDAP_SUCCESS; 57625450Speter} 57725450Speter