1 /* index.c - routines for dealing with attribute indexes */
4 * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved.
5 * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
12 #include <ac/string.h>
13 #include <ac/socket.h>
18 static slap_mask_t index_mask(
20 AttributeDescription *desc,
22 struct berval *atname )
27 bdb_attr_mask( be->be_private, desc, &mask );
30 *atname = desc->ad_cname;
31 *dbname = desc->ad_cname.bv_val;
35 /* If there is a language tag, did we ever index the base
36 * type? If so, check for mask, otherwise it's not there.
38 if( slap_ad_is_lang( desc ) && desc != desc->ad_type->sat_ad ) {
39 /* has language tag */
40 bdb_attr_mask( be->be_private, desc->ad_type->sat_ad, &mask );
42 if (! ( mask & SLAP_INDEX_NOLANG ) ) {
43 *atname = desc->ad_type->sat_cname;
44 *dbname = desc->ad_type->sat_cname.bv_val;
49 /* see if supertype defined mask for its subtypes */
50 for( at = desc->ad_type; at != NULL ; at = at->sat_sup ) {
51 /* If no AD, we've never indexed this type */
52 if ( !at->sat_ad ) continue;
54 bdb_attr_mask( be->be_private, at->sat_ad, &mask );
56 if( mask & SLAP_INDEX_AUTO_SUBTYPES ) {
57 *atname = desc->ad_type->sat_cname;
58 *dbname = at->sat_cname.bv_val;
62 if( !( mask & SLAP_INDEX_NOSUBTYPES ) ) {
63 *atname = at->sat_cname;
64 *dbname = at->sat_cname.bv_val;
76 AttributeDescription *desc,
80 struct berval *prefixp )
87 mask = index_mask( be, desc, &dbname, prefixp );
90 return LDAP_INAPPROPRIATE_MATCHING;
93 rc = bdb_db_cache( be, dbname, &db );
95 if( rc != LDAP_SUCCESS ) {
100 case LDAP_FILTER_PRESENT:
101 if( IS_SLAP_INDEX( mask, SLAP_INDEX_PRESENT ) ) {
106 case LDAP_FILTER_APPROX:
107 if( IS_SLAP_INDEX( mask, SLAP_INDEX_APPROX ) ) {
112 case LDAP_FILTER_EQUALITY:
113 if( IS_SLAP_INDEX( mask, SLAP_INDEX_EQUALITY ) ) {
118 case LDAP_FILTER_SUBSTRINGS:
119 if( IS_SLAP_INDEX( mask, SLAP_INDEX_SUBSTR ) ) {
128 return LDAP_INAPPROPRIATE_MATCHING;
140 struct berval *atname,
141 struct berval **vals,
149 AttributeDescription *ad = NULL;
150 struct berval **keys;
154 rc = bdb_db_cache( be, dbname, &db );
156 if ( rc != LDAP_SUCCESS ) {
158 LDAP_LOG(( "index", LDAP_LEVEL_ERR,
159 "bdb_index_read: Could not open DB %s\n", dbname));
161 Debug( LDAP_DEBUG_ANY,
162 "<= bdb_index_read NULL (could not open %s)\n",
168 rc = slap_bv2ad( atname, &ad, &text );
169 if( rc != LDAP_SUCCESS ) return rc;
171 if( IS_SLAP_INDEX( mask, SLAP_INDEX_PRESENT ) ) {
172 rc = bdb_key_change( be, db, txn, atname, id, op );
178 if( IS_SLAP_INDEX( mask, SLAP_INDEX_EQUALITY ) ) {
179 rc = ad->ad_type->sat_equality->smr_indexer(
180 LDAP_FILTER_EQUALITY,
182 ad->ad_type->sat_syntax,
183 ad->ad_type->sat_equality,
184 atname, vals, &keys );
186 if( rc == LDAP_SUCCESS && keys != NULL ) {
187 for( i=0; keys[i] != NULL; i++ ) {
188 rc = bdb_key_change( be, db, txn, keys[i], id, op );
190 ber_bvecfree( keys );
194 ber_bvecfree( keys );
199 if( IS_SLAP_INDEX( mask, SLAP_INDEX_APPROX ) ) {
200 rc = ad->ad_type->sat_approx->smr_indexer(
203 ad->ad_type->sat_syntax,
204 ad->ad_type->sat_approx,
205 atname, vals, &keys );
207 if( rc == LDAP_SUCCESS && keys != NULL ) {
208 for( i=0; keys[i] != NULL; i++ ) {
209 rc = bdb_key_change( be, db, txn, keys[i], id, op );
211 ber_bvecfree( keys );
215 ber_bvecfree( keys );
221 if( IS_SLAP_INDEX( mask, SLAP_INDEX_SUBSTR ) ) {
222 rc = ad->ad_type->sat_substr->smr_indexer(
223 LDAP_FILTER_SUBSTRINGS,
225 ad->ad_type->sat_syntax,
226 ad->ad_type->sat_substr,
227 atname, vals, &keys );
229 if( rc == LDAP_SUCCESS && keys != NULL ) {
230 for( i=0; keys[i] != NULL; i++ ) {
231 bdb_key_change( be, db, txn, keys[i], id, op );
233 ber_bvecfree( keys );
237 ber_bvecfree( keys );
247 static int index_at_values(
252 struct berval **vals,
259 slap_mask_t mask = 0;
260 slap_mask_t tmpmask = 0;
263 if( type->sat_sup ) {
265 rc = index_at_values( be, txn,
273 /* If this type has no AD, we've never used it before */
275 bdb_attr_mask( be->be_private, type->sat_ad, &mask );
279 *dbnamep = type->sat_cname.bv_val;
280 } else if ( !( tmpmask & SLAP_INDEX_AUTO_SUBTYPES ) ) {
285 rc = indexer( be, txn, *dbnamep,
296 AttributeDescription *desc;
301 desc = ad_find_lang( type, lang );
303 bdb_attr_mask( be->be_private, desc, &tmpmask );
307 dbname = desc->ad_cname.bv_val;
308 lname = desc->ad_cname;
312 if( dbname != NULL ) {
313 rc = indexer( be, txn, dbname, &lname,
318 ch_free( lname.bv_val );
329 int bdb_index_values(
332 AttributeDescription *desc,
333 struct berval **vals,
341 rc = index_at_values( be, txn,
342 desc->ad_type, &desc->ad_lang,
360 LDAP_LOG(( "index", LDAP_LEVEL_ENTRY,
361 "index_entry: %s (%s) %ld\n",
362 op == SLAP_INDEX_ADD_OP ? "add" : "del",
363 e->e_dn, (long) e->e_id ));
365 Debug( LDAP_DEBUG_TRACE, "=> index_entry_%s( %ld, \"%s\" )\n",
366 op == SLAP_INDEX_ADD_OP ? "add" : "del",
367 (long) e->e_id, e->e_dn );
370 /* add each attribute to the indexes */
371 for ( ; ap != NULL; ap = ap->a_next ) {
372 rc = bdb_index_values( be, txn,
373 ap->a_desc, ap->a_vals, e->e_id, op );
375 if( rc != LDAP_SUCCESS ) {
377 LDAP_LOG(( "index", LDAP_LEVEL_ENTRY,
378 "index_entry: success\n" ));
380 Debug( LDAP_DEBUG_TRACE,
381 "<= index_entry_%s( %ld, \"%s\" ) success\n",
382 op == SLAP_INDEX_ADD_OP ? "add" : "del",
383 (long) e->e_id, e->e_dn );
390 LDAP_LOG(( "index", LDAP_LEVEL_ENTRY,
391 "index_entry: success\n" ));
393 Debug( LDAP_DEBUG_TRACE, "<= index_entry_%s( %ld, \"%s\" ) success\n",
394 op == SLAP_INDEX_ADD_OP ? "add" : "del",
395 (long) e->e_id, e->e_dn );