X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=servers%2Fslapd%2Fback-ldbm%2Ffilterindex.c;h=f71c4f13ff8270e791fb283b36569782f8a30d61;hb=b09727567d047cb79c8da8545cca9c8355822185;hp=2c32d50d9fe734ee4000a84b8577dd7a62100f0b;hpb=2a20131eaa6c963884881a48f8ec73df621b4d74;p=openldap diff --git a/servers/slapd/back-ldbm/filterindex.c b/servers/slapd/back-ldbm/filterindex.c index 2c32d50d9f..f71c4f13ff 100644 --- a/servers/slapd/back-ldbm/filterindex.c +++ b/servers/slapd/back-ldbm/filterindex.c @@ -1,4 +1,9 @@ /* filterindex.c - generate the list of candidate entries from a filter */ +/* $OpenLDAP$ */ +/* + * Copyright 1998-2000 The OpenLDAP Foundation, All Rights Reserved. + * COPYING RESTRICTIONS APPLY, see COPYRIGHT file + */ #include "portable.h" @@ -10,19 +15,20 @@ #include "slap.h" #include "back-ldbm.h" -static ID_BLOCK *ava_candidates( Backend *be, Ava *ava, int type ); -static ID_BLOCK *presence_candidates( Backend *be, char *type ); -static ID_BLOCK *approx_candidates( Backend *be, Ava *ava ); -static ID_BLOCK *list_candidates( Backend *be, Filter *flist, int ftype ); -static ID_BLOCK *substring_candidates( Backend *be, Filter *f ); -static ID_BLOCK *substring_comp_candidates( Backend *be, char *type, char *val, int prepost ); - -/* - * test_filter - test a filter against a single entry. - * returns 0 filter matched - * -1 filter did not match - * >0 an ldap error code - */ +static ID_BLOCK *presence_candidates( + Backend *be, + AttributeDescription *desc ); +static ID_BLOCK *equality_candidates( + Backend *be, AttributeAssertion *ava ); +static ID_BLOCK *approx_candidates( + Backend *be, AttributeAssertion *ava ); +static ID_BLOCK *substring_candidates( + Backend *be, + SubstringsAssertion *sub ); +static ID_BLOCK *list_candidates( + Backend *be, + Filter *flist, + int ftype ); ID_BLOCK * filter_candidates( @@ -32,52 +38,147 @@ filter_candidates( { ID_BLOCK *result, *tmp1, *tmp2; +#ifdef NEW_LOGGING + LDAP_LOG(( "filter", LDAP_LEVEL_ENTRY, "filter_candidates: enter\n")); +#else Debug( LDAP_DEBUG_TRACE, "=> filter_candidates\n", 0, 0, 0 ); +#endif + result = NULL; switch ( f->f_choice ) { + case SLAPD_FILTER_DN_ONE: +#ifdef NEW_LOGGING + LDAP_LOG(( "filter", LDAP_LEVEL_DETAIL1, + "filter_candidates: DN ONE (%s)\n", f->f_dn )); +#else + Debug( LDAP_DEBUG_FILTER, "\tDN ONE\n", 0, 0, 0 ); +#endif + + /* an error is treated as an empty list */ + if ( dn2idl( be, f->f_dn, DN_ONE_PREFIX, &result ) != 0 + && result != NULL ) { + idl_free( result ); + result = NULL; + } + break; + + case SLAPD_FILTER_DN_SUBTREE: +#ifdef NEW_LOGGING + LDAP_LOG(( "filter", LDAP_LEVEL_DETAIL1, + "filter_candidates: DN SUBTREE (%s)\n", f->f_dn )); +#else + Debug( LDAP_DEBUG_FILTER, "\tDN SUBTREE\n", 0, 0, 0 ); +#endif + + /* an error is treated as an empty list */ + if ( dn2idl( be, f->f_dn, DN_SUBTREE_PREFIX, &result ) != 0 + && result != NULL ) { + idl_free( result ); + result = NULL; + } + break; + + case LDAP_FILTER_PRESENT: +#ifdef NEW_LOGGING + LDAP_LOG(( "filter", LDAP_LEVEL_DETAIL1, + "filter_candidates: Present (%s)\n", f->f_desc->ad_cname->bv_val )); +#else + Debug( LDAP_DEBUG_FILTER, "\tPRESENT\n", 0, 0, 0 ); +#endif + + result = presence_candidates( be, f->f_desc ); + break; + case LDAP_FILTER_EQUALITY: +#ifdef NEW_LOGGING + LDAP_LOG(( "filter", LDAP_LEVEL_DETAIL1, + "filter_candidates: EQUALITY (%s),(%s)\n", + f->f_ava->aa_desc->ad_cname->bv_val, + f->f_ava->aa_value->bv_val )); +#else Debug( LDAP_DEBUG_FILTER, "\tEQUALITY\n", 0, 0, 0 ); - result = ava_candidates( be, &f->f_ava, LDAP_FILTER_EQUALITY ); +#endif + + result = equality_candidates( be, f->f_ava ); + break; + + case LDAP_FILTER_APPROX: +#ifdef NEW_LOGGING + LDAP_LOG(( "filter", LDAP_LEVEL_DETAIL1, + "filter_candidates: APPROX (%s), (%s)\n", + f->f_ava->aa_desc->ad_cname->bv_val, + f->f_ava->aa_value->bv_val )); +#else + Debug( LDAP_DEBUG_FILTER, "\tAPPROX\n", 0, 0, 0 ); +#endif + + result = approx_candidates( be, f->f_ava ); break; case LDAP_FILTER_SUBSTRINGS: +#ifdef NEW_LOGGING + LDAP_LOG(( "filter", LDAP_LEVEL_DETAIL1, + "filter_candidates: SUBSTRINGS\n")); +#else Debug( LDAP_DEBUG_FILTER, "\tSUBSTRINGS\n", 0, 0, 0 ); - result = substring_candidates( be, f ); +#endif + + result = substring_candidates( be, f->f_sub ); break; case LDAP_FILTER_GE: +#ifdef NEW_LOGGING + LDAP_LOG(( "filter", LDAP_LEVEL_DETAIL1, + "filter_candidates: GE\n")); +#else Debug( LDAP_DEBUG_FILTER, "\tGE\n", 0, 0, 0 ); - result = ava_candidates( be, &f->f_ava, LDAP_FILTER_GE ); +#endif + + result = idl_allids( be ); break; case LDAP_FILTER_LE: +#ifdef NEW_LOGGING + LDAP_LOG(( "filter", LDAP_LEVEL_DETAIL1, + "filter_candidates: LE\n" )); +#else Debug( LDAP_DEBUG_FILTER, "\tLE\n", 0, 0, 0 ); - result = ava_candidates( be, &f->f_ava, LDAP_FILTER_LE ); - break; - - case LDAP_FILTER_PRESENT: - Debug( LDAP_DEBUG_FILTER, "\tPRESENT\n", 0, 0, 0 ); - result = presence_candidates( be, f->f_type ); - break; +#endif - case LDAP_FILTER_APPROX: - Debug( LDAP_DEBUG_FILTER, "\tAPPROX\n", 0, 0, 0 ); - result = approx_candidates( be, &f->f_ava ); + result = idl_allids( be ); break; case LDAP_FILTER_AND: +#ifdef NEW_LOGGING + LDAP_LOG(( "filter", LDAP_LEVEL_DETAIL1, + "filter_candidates: AND\n" )); +#else Debug( LDAP_DEBUG_FILTER, "\tAND\n", 0, 0, 0 ); +#endif + result = list_candidates( be, f->f_and, LDAP_FILTER_AND ); break; case LDAP_FILTER_OR: +#ifdef NEW_LOGGING + LDAP_LOG(( "filter", LDAP_LEVEL_DETAIL1, + "filter_candidates: OR\n" )); +#else Debug( LDAP_DEBUG_FILTER, "\tOR\n", 0, 0, 0 ); +#endif + result = list_candidates( be, f->f_or, LDAP_FILTER_OR ); break; case LDAP_FILTER_NOT: +#ifdef NEW_LOGGING + LDAP_LOG(( "filter", LDAP_LEVEL_DETAIL1, + "filter_candidates: NOT\n" )); +#else Debug( LDAP_DEBUG_FILTER, "\tNOT\n", 0, 0, 0 ); +#endif + tmp1 = idl_allids( be ); tmp2 = filter_candidates( be, f->f_not ); result = idl_notin( be, tmp1, tmp2 ); @@ -86,93 +187,502 @@ filter_candidates( break; } +#ifdef NEW_LOGGING + LDAP_LOG(( "filter", LDAP_LEVEL_ENTRY, + "filter_candidates: return %ld\n", + result ? ID_BLOCK_NIDS(result) : 0 )); +#else Debug( LDAP_DEBUG_TRACE, "<= filter_candidates %ld\n", result ? ID_BLOCK_NIDS(result) : 0, 0, 0 ); +#endif + return( result ); } static ID_BLOCK * -ava_candidates( +presence_candidates( Backend *be, - Ava *ava, - int type + AttributeDescription *desc ) { ID_BLOCK *idl; + DBCache *db; + int rc; + char *dbname; + slap_mask_t mask; + struct berval *prefix; + +#ifdef NEW_LOGGING + LDAP_LOG(( "filter", LDAP_LEVEL_ENTRY, + "presence_candidates: enter\n" )); +#else + Debug( LDAP_DEBUG_TRACE, "=> presence_candidates\n", 0, 0, 0 ); +#endif - Debug( LDAP_DEBUG_TRACE, "=> ava_candidates 0x%x\n", type, 0, 0 ); - switch ( type ) { - case LDAP_FILTER_EQUALITY: - idl = index_read( be, ava->ava_type, INDEX_EQUALITY, - ava->ava_value.bv_val ); - break; + idl = idl_allids( be ); - case LDAP_FILTER_GE: - idl = idl_allids( be ); - break; + rc = index_param( be, desc, LDAP_FILTER_PRESENT, + &dbname, &mask, &prefix ); - case LDAP_FILTER_LE: - idl = idl_allids( be ); - break; + if( rc != LDAP_SUCCESS ) { +#ifdef NEW_LOGGING + LDAP_LOG(( "filter", LDAP_LEVEL_INFO, + "presence_candidates: index_param returned %d\n", + rc )); +#else + Debug( LDAP_DEBUG_TRACE, + "<= presence_candidates: index_param returned=%d\n", + rc, 0, 0 ); +#endif + + return idl; + } + + if( dbname == NULL ) { + /* not indexed */ +#ifdef NEW_LOGGING + LDAP_LOG(( "filter", LDAP_LEVEL_INFO, + "presence_candidates: not indexed\n" )); +#else + Debug( LDAP_DEBUG_TRACE, + "<= presense_candidates: not indexed\n", + 0, 0, 0 ); +#endif + + ber_bvfree( prefix ); + return idl; + } + + db = ldbm_cache_open( be, dbname, LDBM_SUFFIX, LDBM_READER ); + + if ( db == NULL ) { +#ifdef NEW_LOGGING + LDAP_LOG(( "filter", LDAP_LEVEL_INFO, + "presence_candidates: db open failed (%s%s)\n", + dbname, LDBM_SUFFIX )); +#else + Debug( LDAP_DEBUG_ANY, + "<= presense_candidates db open failed (%s%s)\n", + dbname, LDBM_SUFFIX, 0 ); +#endif + + ber_bvfree( prefix ); + return idl; + } + + if( prefix != NULL ) { + idl_free( idl ); + idl = NULL; + + rc = key_read( be, db, prefix, &idl ); + + if( rc != LDAP_SUCCESS ) { +#ifdef NEW_LOGGING + LDAP_LOG(( "filter", LDAP_LEVEL_ERR, + "presence_candidates: key read failed (%d)\n", rc )); +#else + Debug( LDAP_DEBUG_TRACE, + "<= presense_candidates key read failed (%d)\n", + rc, 0, 0 ); +#endif + + + } else if( idl == NULL ) { +#ifdef NEW_LOGGING + LDAP_LOG(( "filter", LDAP_LEVEL_DETAIL1, + "presence_candidates: NULL\n" )); +#else + Debug( LDAP_DEBUG_TRACE, + "<= presense_candidates NULL\n", + 0, 0, 0 ); +#endif + + } } - Debug( LDAP_DEBUG_TRACE, "<= ava_candidates %ld\n", + ldbm_cache_close( be, db ); + ber_bvfree( prefix ); + +#ifdef NEW_LOGGING + LDAP_LOG(( "filter", LDAP_LEVEL_ENTRY, + "presence_candidates: return %ld\n", + idl ? ID_BLOCK_NIDS(idl) : 0 )); +#else + Debug( LDAP_DEBUG_TRACE, "<= presence_candidates %ld\n", idl ? ID_BLOCK_NIDS(idl) : 0, 0, 0 ); +#endif + return( idl ); } static ID_BLOCK * -presence_candidates( +equality_candidates( Backend *be, - char *type + AttributeAssertion *ava ) { ID_BLOCK *idl; + DBCache *db; + int i; + int rc; + char *dbname; + slap_mask_t mask; + struct berval *prefix; + struct berval **keys = NULL; + MatchingRule *mr; + +#ifdef NEW_LOGGING + LDAP_LOG(( "filter", LDAP_LEVEL_ENTRY, + "equality_candidates: enter\n" )); +#else + Debug( LDAP_DEBUG_TRACE, "=> equality_candidates\n", 0, 0, 0 ); +#endif + + + idl = idl_allids( be ); + + rc = index_param( be, ava->aa_desc, LDAP_FILTER_EQUALITY, + &dbname, &mask, &prefix ); + + if( rc != LDAP_SUCCESS ) { +#ifdef NEW_LOGGING + LDAP_LOG(( "filter", LDAP_LEVEL_ERR, + "equality_candidates: index_param returned %d\n", rc )); +#else + Debug( LDAP_DEBUG_TRACE, + "<= equality_candidates: index_param returned=%d\n", + rc, 0, 0 ); +#endif + + return idl; + } - Debug( LDAP_DEBUG_TRACE, "=> presence_candidates\n", 0, 0, 0 ); + if( dbname == NULL ) { + /* not indexed */ +#ifdef NEW_LOGGING + LDAP_LOG(( "filter", LDAP_LEVEL_ERR, + "equality_candidates: not indexed\n" )); +#else + Debug( LDAP_DEBUG_TRACE, + "<= equality_candidates: not indexed\n", + 0, 0, 0 ); +#endif + + ber_bvfree( prefix ); + return idl; + } - idl = index_read( be, type, 0, "*" ); + mr = ava->aa_desc->ad_type->sat_equality; + if( !mr ) { + ber_bvfree( prefix ); + return idl; + } - Debug( LDAP_DEBUG_TRACE, "<= presence_candidates %ld\n", + if( !mr->smr_filter ) { + ber_bvfree( prefix ); + return idl; + } + + rc = (mr->smr_filter)( + LDAP_FILTER_EQUALITY, + mask, + ava->aa_desc->ad_type->sat_syntax, + mr, + prefix, + ava->aa_value, + &keys ); + + ber_bvfree( prefix ); + + if( rc != LDAP_SUCCESS ) { +#ifdef NEW_LOGGING + LDAP_LOG(( "filter", LDAP_LEVEL_ERR, + "equality_candidates: (%s%s) MR filter failed (%d\n", + dbname, LDBM_SUFFIX, rc )); +#else + Debug( LDAP_DEBUG_TRACE, + "<= equality_candidates: (%s%s) MR filter failed (%d)\n", + dbname, LDBM_SUFFIX, rc ); +#endif + + return idl; + } + + if( keys == NULL ) { +#ifdef NEW_LOGGING + LDAP_LOG(( "filter", LDAP_LEVEL_ERR, + "equality_candidates: no keys (%s%s)\n", + dbname, LDBM_SUFFIX )); +#else + Debug( LDAP_DEBUG_TRACE, + "<= equality_candidates: no keys (%s%s)\n", + dbname, LDBM_SUFFIX, 0 ); +#endif + + return idl; + } + + db = ldbm_cache_open( be, dbname, LDBM_SUFFIX, LDBM_READER ); + + if ( db == NULL ) { +#ifdef NEW_LOGGING + LDAP_LOG(( "filter", LDAP_LEVEL_ERR, + "equality_candidates: db open failed (%s%s)\n", + dbname, LDBM_SUFFIX )); +#else + Debug( LDAP_DEBUG_ANY, + "<= equality_candidates db open failed (%s%s)\n", + dbname, LDBM_SUFFIX, 0 ); +#endif + + return idl; + } + + for ( i= 0; keys[i] != NULL; i++ ) { + ID_BLOCK *save; + ID_BLOCK *tmp; + + rc = key_read( be, db, keys[i], &tmp ); + + if( rc != LDAP_SUCCESS ) { + idl_free( idl ); + idl = NULL; +#ifdef NEW_LOGGING + LDAP_LOG(( "filter", LDAP_LEVEL_ERR, + "equality_candidates: key read failed (%d)\n", rc )); +#else + Debug( LDAP_DEBUG_TRACE, + "<= equality_candidates key read failed (%d)\n", + rc, 0, 0 ); +#endif + + break; + } + + if( tmp == NULL ) { + idl_free( idl ); + idl = NULL; +#ifdef NEW_LOGGING + LDAP_LOG(( "filter", LDAP_LEVEL_INFO, + "equality_candidates NULL\n" )); +#else + Debug( LDAP_DEBUG_TRACE, + "<= equality_candidates NULL\n", + 0, 0, 0 ); +#endif + + break; + } + + save = idl; + idl = idl_intersection( be, idl, tmp ); + idl_free( save ); + idl_free( tmp ); + + if( idl == NULL ) break; + } + + ber_bvecfree( keys ); + + ldbm_cache_close( be, db ); + + +#ifdef NEW_LOGGING + LDAP_LOG(( "filter", LDAP_LEVEL_ENTRY, + "equality_candidates: return %ld\n", + idl ? ID_BLOCK_NIDS(idl) : 0 )); +#else + Debug( LDAP_DEBUG_TRACE, "<= equality_candidates %ld\n", idl ? ID_BLOCK_NIDS(idl) : 0, 0, 0 ); +#endif + return( idl ); } static ID_BLOCK * approx_candidates( Backend *be, - Ava *ava + AttributeAssertion *ava ) { - char *w, *c; - ID_BLOCK *idl, *tmp; - + ID_BLOCK *idl; + DBCache *db; + int i; + int rc; + char *dbname; + slap_mask_t mask; + struct berval *prefix; + struct berval **keys = NULL; + MatchingRule *mr; + +#ifdef NEW_LOGGING + LDAP_LOG(( "filter", LDAP_LEVEL_ENTRY, + "approx_candidates: enter\n" )); +#else Debug( LDAP_DEBUG_TRACE, "=> approx_candidates\n", 0, 0, 0 ); +#endif - idl = NULL; - for ( w = first_word( ava->ava_value.bv_val ); w != NULL; - w = next_word( w ) ) { - c = phonetic( w ); - if ( (tmp = index_read( be, ava->ava_type, INDEX_APPROX, c )) - == NULL ) { - free( c ); + + idl = idl_allids( be ); + + rc = index_param( be, ava->aa_desc, LDAP_FILTER_APPROX, + &dbname, &mask, &prefix ); + + if( rc != LDAP_SUCCESS ) { +#ifdef NEW_LOGGING + LDAP_LOG(( "filter", LDAP_LEVEL_ERR, + "approx_candidates: index_param returned %d\n", rc )); +#else + Debug( LDAP_DEBUG_TRACE, + "<= approx_candidates: index_param returned=%d\n", + rc, 0, 0 ); +#endif + + return idl; + } + + if( dbname == NULL ) { + /* not indexed */ +#ifdef NEW_LOGGING + LDAP_LOG(( "filter", LDAP_LEVEL_ERR, + "approx_candidates: not indexed\n" )); +#else + Debug( LDAP_DEBUG_ANY, + "<= approx_candidates: not indexed\n", + 0, 0, 0 ); +#endif + + ber_bvfree( prefix ); + return idl; + } + + mr = ava->aa_desc->ad_type->sat_approx; + if( !mr ) { + /* no approx matching rule, try equality matching rule */ + mr = ava->aa_desc->ad_type->sat_equality; + } + + if( !mr ) { + ber_bvfree( prefix ); + return idl; + } + + if( !mr->smr_filter ) { + ber_bvfree( prefix ); + return idl; + } + + rc = (mr->smr_filter)( + LDAP_FILTER_APPROX, + mask, + ava->aa_desc->ad_type->sat_syntax, + mr, + prefix, + ava->aa_value, + &keys ); + + ber_bvfree( prefix ); + + if( rc != LDAP_SUCCESS ) { +#ifdef NEW_LOGGING + LDAP_LOG(( "filter", LDAP_LEVEL_ERR, + "approx_candidates: (%s%s) MR filter failed (%d)\n", + dbname, LDBM_SUFFIX, rc )); +#else + Debug( LDAP_DEBUG_TRACE, + "<= approx_candidates: (%s%s) MR filter failed (%d)\n", + dbname, LDBM_SUFFIX, rc ); +#endif + + return idl; + } + + if( keys == NULL ) { +#ifdef NEW_LOGGING + LDAP_LOG(( "filter", LDAP_LEVEL_INFO, + "approx_candidates: no keys (%s%s)\n", + dbname, LDBM_SUFFIX )); +#else + Debug( LDAP_DEBUG_TRACE, + "<= approx_candidates: no keys (%s%s)\n", + dbname, LDBM_SUFFIX, 0 ); +#endif + + return idl; + } + + db = ldbm_cache_open( be, dbname, LDBM_SUFFIX, LDBM_READER ); + + if ( db == NULL ) { +#ifdef NEW_LOGGING + LDAP_LOG(( "filter", LDAP_LEVEL_ERR, + "approx_candidates db open failed (%s%s)\n", + dbname, LDBM_SUFFIX )); +#else + Debug( LDAP_DEBUG_ANY, + "<= approx_candidates db open failed (%s%s)\n", + dbname, LDBM_SUFFIX, 0 ); +#endif + + return idl; + } + + for ( i= 0; keys[i] != NULL; i++ ) { + ID_BLOCK *save; + ID_BLOCK *tmp; + + rc = key_read( be, db, keys[i], &tmp ); + + if( rc != LDAP_SUCCESS ) { + idl_free( idl ); + idl = NULL; +#ifdef NEW_LOGGING + LDAP_LOG(( "filter", LDAP_LEVEL_ERR, + "approx_candidates: key read failed (%d)\n", rc )); +#else + Debug( LDAP_DEBUG_TRACE, "<= approx_candidates key read failed (%d)\n", + rc, 0, 0 ); +#endif + + break; + } + + if( tmp == NULL ) { idl_free( idl ); + idl = NULL; +#ifdef NEW_LOGGING + LDAP_LOG(( "filter", LDAP_LEVEL_INFO, + "approx_candidates: NULL\n" )); +#else Debug( LDAP_DEBUG_TRACE, "<= approx_candidates NULL\n", 0, 0, 0 ); - return( NULL ); - } - free( c ); +#endif - if ( idl == NULL ) { - idl = tmp; - } else { - idl = idl_intersection( be, idl, tmp ); + break; } + + save = idl; + idl = idl_intersection( be, idl, tmp ); + idl_free( save ); + idl_free( tmp ); + + if( idl == NULL ) break; } + ber_bvecfree( keys ); + + ldbm_cache_close( be, db ); + +#ifdef NEW_LOGGING + LDAP_LOG(( "filter", LDAP_LEVEL_ENTRY, + "approx_candidates: return %ld\n", + idl ? ID_BLOCK_NIDS(idl) : 0 )); +#else Debug( LDAP_DEBUG_TRACE, "<= approx_candidates %ld\n", idl ? ID_BLOCK_NIDS(idl) : 0, 0, 0 ); +#endif + return( idl ); } @@ -186,16 +696,28 @@ list_candidates( ID_BLOCK *idl, *tmp, *tmp2; Filter *f; +#ifdef NEW_LOGGING + LDAP_LOG(( "filter", LDAP_LEVEL_ENTRY, + "list_candidates: 0x%x\n", ftype )); +#else Debug( LDAP_DEBUG_TRACE, "=> list_candidates 0x%x\n", ftype, 0, 0 ); +#endif + idl = NULL; for ( f = flist; f != NULL; f = f->f_next ) { if ( (tmp = filter_candidates( be, f )) == NULL && ftype == LDAP_FILTER_AND ) { - Debug( LDAP_DEBUG_TRACE, - "<= list_candidates NULL\n", 0, 0, 0 ); - idl_free( idl ); - return( NULL ); +#ifdef NEW_LOGGING + LDAP_LOG(( "filter", LDAP_LEVEL_INFO, + "list_candidates: NULL\n" )); +#else + Debug( LDAP_DEBUG_TRACE, + "<= list_candidates NULL\n", 0, 0, 0 ); +#endif + + idl_free( idl ); + return( NULL ); } tmp2 = idl; @@ -212,142 +734,197 @@ list_candidates( } } +#ifdef NEW_LOGGING + LDAP_LOG(( "filter", LDAP_LEVEL_ENTRY, + "list_candidates: return %ld\n", + idl ? ID_BLOCK_NIDS(idl) : 0 )); +#else Debug( LDAP_DEBUG_TRACE, "<= list_candidates %ld\n", idl ? ID_BLOCK_NIDS(idl) : 0, 0, 0 ); +#endif + return( idl ); } static ID_BLOCK * substring_candidates( Backend *be, - Filter *f + SubstringsAssertion *sub ) { - int i; - ID_BLOCK *idl, *tmp, *tmp2; + ID_BLOCK *idl; + DBCache *db; + int i; + int rc; + char *dbname; + slap_mask_t mask; + struct berval *prefix; + struct berval **keys = NULL; + MatchingRule *mr; + +#ifdef NEW_LOGGING + LDAP_LOG(( "filter", LDAP_LEVEL_ENTRY, + "substrings_candidates: enter\n" )); +#else + Debug( LDAP_DEBUG_TRACE, "=> substrings_candidates\n", 0, 0, 0 ); +#endif + + + idl = idl_allids( be ); + + rc = index_param( be, sub->sa_desc, LDAP_FILTER_SUBSTRINGS, + &dbname, &mask, &prefix ); + + if( rc != LDAP_SUCCESS ) { +#ifdef NEW_LOGGING + LDAP_LOG(( "filter", LDAP_LEVEL_ERR, + "substrings_candidates: index_param returned %d\n", rc )); +#else + Debug( LDAP_DEBUG_TRACE, + "<= substrings_candidates: index_param returned=%d\n", + rc, 0, 0 ); +#endif + + return idl; + } - Debug( LDAP_DEBUG_TRACE, "=> substring_candidates\n", 0, 0, 0 ); + if( dbname == NULL ) { + /* not indexed */ +#ifdef NEW_LOGGING + LDAP_LOG(( "filter", LDAP_LEVEL_ERR, + "substrings_candidates: not indexed\n" )); +#else + Debug( LDAP_DEBUG_ANY, + "<= substrings_candidates: not indexed\n", + 0, 0, 0 ); +#endif + + ber_bvfree( prefix ); + return idl; + } - idl = NULL; + mr = sub->sa_desc->ad_type->sat_substr; - /* initial */ - if ( f->f_sub_initial != NULL ) { - if ( (int) strlen( f->f_sub_initial ) < SUBLEN - 1 ) { - idl = idl_allids( be ); - } else if ( (idl = substring_comp_candidates( be, f->f_sub_type, - f->f_sub_initial, '^' )) == NULL ) { - return( NULL ); - } + if( !mr ) { + ber_bvfree( prefix ); + return idl; } - /* final */ - if ( f->f_sub_final != NULL ) { - if ( (int) strlen( f->f_sub_final ) < SUBLEN - 1 ) { - tmp = idl_allids( be ); - } else if ( (tmp = substring_comp_candidates( be, f->f_sub_type, - f->f_sub_final, '$' )) == NULL ) { - idl_free( idl ); - return( NULL ); - } + if( !mr->smr_filter ) { + ber_bvfree( prefix ); + return idl; + } - if ( idl == NULL ) { - idl = tmp; - } else { - tmp2 = idl; - idl = idl_intersection( be, idl, tmp ); - idl_free( tmp ); - idl_free( tmp2 ); - } + rc = (mr->smr_filter)( + LDAP_FILTER_SUBSTRINGS, + mask, + sub->sa_desc->ad_type->sat_syntax, + mr, + prefix, + sub, + &keys ); + + ber_bvfree( prefix ); + + if( rc != LDAP_SUCCESS ) { +#ifdef NEW_LOGGING + LDAP_LOG(( "filter", LDAP_LEVEL_ERR, + "substrings_candidates: (%s%s) MR filter failed (%d)\n", + dbname, LDBM_SUFFIX, rc )); +#else + Debug( LDAP_DEBUG_TRACE, + "<= substrings_candidates: (%s%s) MR filter failed (%d)\n", + dbname, LDBM_SUFFIX, rc ); +#endif + + return idl; } - for ( i = 0; f->f_sub_any != NULL && f->f_sub_any[i] != NULL; i++ ) { - if ( (int) strlen( f->f_sub_any[i] ) < SUBLEN ) { - tmp = idl_allids( be ); - } else if ( (tmp = substring_comp_candidates( be, f->f_sub_type, - f->f_sub_any[i], 0 )) == NULL ) { - idl_free( idl ); - return( NULL ); - } + if( keys == NULL ) { +#ifdef NEW_LOGGING + LDAP_LOG(( "filter", LDAP_LEVEL_ERR, + "substrings_candidates: (0x%04lx) no keys (%s%s)\n", + mask, dbname, LDBM_SUFFIX )); +#else + Debug( LDAP_DEBUG_TRACE, + "<= substrings_candidates: (0x%04lx) no keys (%s%s)\n", + mask, dbname, LDBM_SUFFIX ); +#endif + + return idl; + } - if ( idl == NULL ) { - idl = tmp; - } else { - tmp2 = idl; - idl = idl_intersection( be, idl, tmp ); - idl_free( tmp ); - idl_free( tmp2 ); - } + db = ldbm_cache_open( be, dbname, LDBM_SUFFIX, LDBM_READER ); + + if ( db == NULL ) { +#ifdef NEW_LOGGING + LDAP_LOG(( "filter", LDAP_LEVEL_ERR, + "substrings_candidates: db open failed (%s%s)\n", + dbname, LDBM_SUFFIX )); +#else + Debug( LDAP_DEBUG_ANY, + "<= substrings_candidates db open failed (%s%s)\n", + dbname, LDBM_SUFFIX, 0 ); +#endif + + return idl; } - Debug( LDAP_DEBUG_TRACE, "<= substring_candidates %ld\n", - idl ? ID_BLOCK_NIDS(idl) : 0, 0, 0 ); - return( idl ); -} + for ( i= 0; keys[i] != NULL; i++ ) { + ID_BLOCK *save; + ID_BLOCK *tmp; -static ID_BLOCK * -substring_comp_candidates( - Backend *be, - char *type, - char *val, - int prepost -) -{ - int i, len; - ID_BLOCK *idl, *tmp, *tmp2; - char *p; - char buf[SUBLEN + 1]; + rc = key_read( be, db, keys[i], &tmp ); - Debug( LDAP_DEBUG_TRACE, "=> substring_comp_candidates\n", 0, 0, 0 ); + if( rc != LDAP_SUCCESS ) { + idl_free( idl ); + idl = NULL; +#ifdef NEW_LOGGING + LDAP_LOG(( "filter", LDAP_LEVEL_ERR, + "substrings_candidates: key read failed (%d)\n", + rc )); +#else + Debug( LDAP_DEBUG_TRACE, "<= substrings_candidates key read failed (%d)\n", + rc, 0, 0 ); +#endif + + break; + } - len = strlen( val ); - idl = NULL; + if( tmp == NULL ) { + idl_free( idl ); + idl = NULL; +#ifdef NEW_LOGGING + LDAP_LOG(( "filter", LDAP_LEVEL_INFO, + "substrings_candidates: NULL\n" )); +#else + Debug( LDAP_DEBUG_TRACE, "<= substrings_candidates NULL\n", + 0, 0, 0 ); +#endif - /* prepend ^ for initial substring */ - if ( prepost == '^' ) { - buf[0] = '^'; - for ( i = 0; i < SUBLEN - 1; i++ ) { - buf[i + 1] = val[i]; + break; } - buf[SUBLEN] = '\0'; - if ( (idl = index_read( be, type, INDEX_SUB, buf )) == NULL ) { - return( NULL ); - } - } else if ( prepost == '$' ) { - p = val + len - SUBLEN + 1; - for ( i = 0; i < SUBLEN - 1; i++ ) { - buf[i] = p[i]; - } - buf[SUBLEN - 1] = '$'; - buf[SUBLEN] = '\0'; + save = idl; + idl = idl_intersection( be, idl, tmp ); + idl_free( save ); + idl_free( tmp ); - if ( (idl = index_read( be, type, INDEX_SUB, buf )) == NULL ) { - return( NULL ); - } + if( idl == NULL ) break; } - for ( p = val; p < (val + len - SUBLEN + 1); p++ ) { - for ( i = 0; i < SUBLEN; i++ ) { - buf[i] = p[i]; - } - buf[SUBLEN] = '\0'; - - if ( (tmp = index_read( be, type, INDEX_SUB, buf )) == NULL ) { - idl_free( idl ); - return( NULL ); - } + ber_bvecfree( keys ); - if ( idl == NULL ) { - idl = tmp; - } else { - tmp2 = idl; - idl = idl_intersection( be, idl, tmp ); - idl_free( tmp ); - idl_free( tmp2 ); - } - } + ldbm_cache_close( be, db ); - Debug( LDAP_DEBUG_TRACE, "<= substring_comp_candidates %ld\n", +#ifdef NEW_LOGGING + LDAP_LOG(( "filter", LDAP_LEVEL_ENTRY, + "substrings_candidates: return %ld\n", + idl ? ID_BLOCK_NIDS(idl) : 0 )); +#else + Debug( LDAP_DEBUG_TRACE, "<= substrings_candidates %ld\n", idl ? ID_BLOCK_NIDS(idl) : 0, 0, 0 ); +#endif + return( idl ); }