1 /* filterindex.c - generate the list of candidate entries from a filter */
3 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
5 * Copyright 2000-2004 The OpenLDAP Foundation.
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted only as authorized by the OpenLDAP
12 * A copy of this license is available in the file LICENSE in the
13 * top-level directory of the distribution or, alternatively, at
14 * <http://www.OpenLDAP.org/license.html>.
20 #include <ac/string.h>
25 static int presence_candidates(
27 AttributeDescription *desc,
30 static int equality_candidates(
32 AttributeAssertion *ava,
35 static int inequality_candidates(
37 AttributeAssertion *ava,
41 static int approx_candidates(
43 AttributeAssertion *ava,
46 static int substring_candidates(
48 SubstringsAssertion *sub,
52 static int list_candidates(
61 bdb_filter_candidates(
69 Debug( LDAP_DEBUG_FILTER, "=> bdb_filter_candidates\n", 0, 0, 0 );
71 switch ( f->f_choice ) {
72 case SLAPD_FILTER_COMPUTED:
73 switch( f->f_result ) {
74 case SLAPD_COMPARE_UNDEFINED:
75 /* This technically is not the same as FALSE, but it
76 * certainly will produce no matches.
79 case LDAP_COMPARE_FALSE:
82 case LDAP_COMPARE_TRUE: {
83 struct bdb_info *bdb = (struct bdb_info *)op->o_bd->be_private;
84 BDB_IDL_ALL( bdb, ids );
87 /* this is a pre-computed scope, leave it alone */
91 case LDAP_FILTER_PRESENT:
92 Debug( LDAP_DEBUG_FILTER, "\tPRESENT\n", 0, 0, 0 );
93 rc = presence_candidates( op, f->f_desc, ids );
96 case LDAP_FILTER_EQUALITY:
97 Debug( LDAP_DEBUG_FILTER, "\tEQUALITY\n", 0, 0, 0 );
98 rc = equality_candidates( op, f->f_ava, ids, tmp );
101 case LDAP_FILTER_APPROX:
102 Debug( LDAP_DEBUG_FILTER, "\tAPPROX\n", 0, 0, 0 );
103 rc = approx_candidates( op, f->f_ava, ids, tmp );
106 case LDAP_FILTER_SUBSTRINGS:
107 Debug( LDAP_DEBUG_FILTER, "\tSUBSTRINGS\n", 0, 0, 0 );
108 rc = substring_candidates( op, f->f_sub, ids, tmp );
112 /* if no GE index, use pres */
113 Debug( LDAP_DEBUG_FILTER, "\tGE\n", 0, 0, 0 );
114 if( f->f_ava->aa_desc->ad_type->sat_ordering &&
115 ( f->f_ava->aa_desc->ad_type->sat_ordering->smr_usage && SLAP_MR_ORDERED_INDEX ) )
116 rc = inequality_candidates( op, f->f_ava, ids, tmp, LDAP_FILTER_GE );
118 rc = presence_candidates( op, f->f_ava->aa_desc, ids );
122 /* if no LE index, use pres */
123 Debug( LDAP_DEBUG_FILTER, "\tLE\n", 0, 0, 0 );
124 if( f->f_ava->aa_desc->ad_type->sat_ordering &&
125 ( f->f_ava->aa_desc->ad_type->sat_ordering->smr_usage && SLAP_MR_ORDERED_INDEX ) )
126 rc = inequality_candidates( op, f->f_ava, ids, tmp, LDAP_FILTER_LE );
128 rc = presence_candidates( op, f->f_ava->aa_desc, ids );
131 case LDAP_FILTER_NOT:
132 /* no indexing to support NOT filters */
133 Debug( LDAP_DEBUG_FILTER, "\tNOT\n", 0, 0, 0 );
134 { struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
135 BDB_IDL_ALL( bdb, ids );
139 case LDAP_FILTER_AND:
140 Debug( LDAP_DEBUG_FILTER, "\tAND\n", 0, 0, 0 );
141 rc = list_candidates( op,
142 f->f_and, LDAP_FILTER_AND, ids, tmp, stack );
146 Debug( LDAP_DEBUG_FILTER, "\tOR\n", 0, 0, 0 );
147 rc = list_candidates( op,
148 f->f_or, LDAP_FILTER_OR, ids, tmp, stack );
152 Debug( LDAP_DEBUG_FILTER, "\tUNKNOWN %lu\n",
153 (unsigned long) f->f_choice, 0, 0 );
154 /* Must not return NULL, otherwise extended filters break */
155 { struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
156 BDB_IDL_ALL( bdb, ids );
160 Debug( LDAP_DEBUG_FILTER,
161 "<= bdb_filter_candidates: id=%ld first=%ld last=%ld\n",
163 (long) BDB_IDL_FIRST( ids ),
164 (long) BDB_IDL_LAST( ids ) );
178 struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
182 Debug( LDAP_DEBUG_FILTER, "=> bdb_list_candidates 0x%x\n", ftype, 0, 0 );
183 for ( f = flist; f != NULL; f = f->f_next ) {
184 /* ignore precomputed scopes */
185 if ( f->f_choice == SLAPD_FILTER_COMPUTED &&
186 f->f_result == LDAP_SUCCESS ) {
189 BDB_IDL_ZERO( save );
190 rc = bdb_filter_candidates( op, f, save, tmp,
191 save+BDB_IDL_UM_SIZE );
194 if ( ftype == LDAP_FILTER_AND ) {
202 if ( ftype == LDAP_FILTER_AND ) {
204 BDB_IDL_CPY( ids, save );
206 bdb_idl_intersection( ids, save );
208 if( BDB_IDL_IS_ZERO( ids ) )
212 BDB_IDL_CPY( ids, save );
214 bdb_idl_union( ids, save );
219 if( rc == LDAP_SUCCESS ) {
220 Debug( LDAP_DEBUG_FILTER,
221 "<= bdb_list_candidates: id=%ld first=%ld last=%ld\n",
223 (long) BDB_IDL_FIRST(ids),
224 (long) BDB_IDL_LAST(ids) );
227 Debug( LDAP_DEBUG_FILTER,
228 "<= bdb_list_candidates: undefined rc=%d\n",
238 AttributeDescription *desc,
241 struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
245 struct berval prefix = {0, NULL};
247 Debug( LDAP_DEBUG_TRACE, "=> bdb_presence_candidates (%s)\n",
248 desc->ad_cname.bv_val, 0, 0 );
250 BDB_IDL_ALL( bdb, ids );
252 if( desc == slap_schema.si_ad_objectClass ) {
256 rc = bdb_index_param( op->o_bd, desc, LDAP_FILTER_PRESENT,
257 &db, &mask, &prefix );
259 if( rc != LDAP_SUCCESS ) {
260 Debug( LDAP_DEBUG_TRACE,
261 "<= bdb_presence_candidates: (%s) index_param "
263 desc->ad_cname.bv_val, rc, 0 );
269 Debug( LDAP_DEBUG_TRACE,
270 "<= bdb_presence_candidates: (%s) not indexed\n",
271 desc->ad_cname.bv_val, 0, 0 );
275 if( prefix.bv_val == NULL ) {
276 Debug( LDAP_DEBUG_TRACE,
277 "<= bdb_presence_candidates: (%s) no prefix\n",
278 desc->ad_cname.bv_val, 0, 0 );
282 rc = bdb_key_read( op->o_bd, db, NULL, &prefix, ids, NULL, 0 );
284 if( rc == DB_NOTFOUND ) {
287 } else if( rc != LDAP_SUCCESS ) {
288 Debug( LDAP_DEBUG_TRACE,
289 "<= bdb_presense_candidates: (%s) "
290 "key read failed (%d)\n",
291 desc->ad_cname.bv_val, rc, 0 );
295 Debug(LDAP_DEBUG_TRACE,
296 "<= bdb_presence_candidates: id=%ld first=%ld last=%ld\n",
298 (long) BDB_IDL_FIRST(ids),
299 (long) BDB_IDL_LAST(ids) );
308 AttributeAssertion *ava,
312 struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
317 struct berval prefix = {0, NULL};
318 struct berval *keys = NULL;
321 Debug( LDAP_DEBUG_TRACE, "=> bdb_equality_candidates (%s)\n",
322 ava->aa_desc->ad_cname.bv_val, 0, 0 );
324 BDB_IDL_ALL( bdb, ids );
326 rc = bdb_index_param( op->o_bd, ava->aa_desc, LDAP_FILTER_EQUALITY,
327 &db, &mask, &prefix );
329 if( rc != LDAP_SUCCESS ) {
330 Debug( LDAP_DEBUG_ANY,
331 "<= bdb_equality_candidates: (%s) "
332 "index_param failed (%d)\n",
333 ava->aa_desc->ad_cname.bv_val, rc, 0 );
338 Debug( LDAP_DEBUG_ANY,
339 "<= bdb_equality_candidates: (%s) not indexed\n",
340 ava->aa_desc->ad_cname.bv_val, 0, 0 );
344 mr = ava->aa_desc->ad_type->sat_equality;
349 if( !mr->smr_filter ) {
353 rc = (mr->smr_filter)(
354 LDAP_FILTER_EQUALITY,
356 ava->aa_desc->ad_type->sat_syntax,
360 &keys, op->o_tmpmemctx );
362 if( rc != LDAP_SUCCESS ) {
363 Debug( LDAP_DEBUG_TRACE,
364 "<= bdb_equality_candidates: (%s, %s) "
365 "MR filter failed (%d)\n",
366 prefix.bv_val, ava->aa_desc->ad_cname.bv_val, rc );
371 Debug( LDAP_DEBUG_TRACE,
372 "<= bdb_equality_candidates: (%s) no keys\n",
373 ava->aa_desc->ad_cname.bv_val, 0, 0 );
377 for ( i= 0; keys[i].bv_val != NULL; i++ ) {
378 rc = bdb_key_read( op->o_bd, db, NULL, &keys[i], tmp, NULL, 0 );
380 if( rc == DB_NOTFOUND ) {
384 } else if( rc != LDAP_SUCCESS ) {
385 Debug( LDAP_DEBUG_TRACE,
386 "<= bdb_equality_candidates: (%s) "
387 "key read failed (%d)\n",
388 ava->aa_desc->ad_cname.bv_val, rc, 0 );
392 if( BDB_IDL_IS_ZERO( tmp ) ) {
393 Debug( LDAP_DEBUG_TRACE,
394 "<= bdb_equality_candidates: (%s) NULL\n",
395 ava->aa_desc->ad_cname.bv_val, 0, 0 );
401 BDB_IDL_CPY( ids, tmp );
403 bdb_idl_intersection( ids, tmp );
406 if( BDB_IDL_IS_ZERO( ids ) )
410 ber_bvarray_free_x( keys, op->o_tmpmemctx );
412 Debug( LDAP_DEBUG_TRACE,
413 "<= bdb_equality_candidates: id=%ld, first=%ld, last=%ld\n",
415 (long) BDB_IDL_FIRST(ids),
416 (long) BDB_IDL_LAST(ids) );
424 AttributeAssertion *ava,
428 struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
433 struct berval prefix = {0, NULL};
434 struct berval *keys = NULL;
437 Debug( LDAP_DEBUG_TRACE, "=> bdb_approx_candidates (%s)\n",
438 ava->aa_desc->ad_cname.bv_val, 0, 0 );
440 BDB_IDL_ALL( bdb, ids );
442 rc = bdb_index_param( op->o_bd, ava->aa_desc, LDAP_FILTER_APPROX,
443 &db, &mask, &prefix );
445 if( rc != LDAP_SUCCESS ) {
446 Debug( LDAP_DEBUG_ANY,
447 "<= bdb_approx_candidates: (%s) "
448 "index_param failed (%d)\n",
449 ava->aa_desc->ad_cname.bv_val, rc, 0 );
454 Debug( LDAP_DEBUG_ANY,
455 "<= bdb_approx_candidates: (%s) not indexed\n",
456 ava->aa_desc->ad_cname.bv_val, 0, 0 );
460 mr = ava->aa_desc->ad_type->sat_approx;
462 /* no approx matching rule, try equality matching rule */
463 mr = ava->aa_desc->ad_type->sat_equality;
470 if( !mr->smr_filter ) {
474 rc = (mr->smr_filter)(
477 ava->aa_desc->ad_type->sat_syntax,
481 &keys, op->o_tmpmemctx );
483 if( rc != LDAP_SUCCESS ) {
484 Debug( LDAP_DEBUG_TRACE,
485 "<= bdb_approx_candidates: (%s, %s) "
486 "MR filter failed (%d)\n",
487 prefix.bv_val, ava->aa_desc->ad_cname.bv_val, rc );
492 Debug( LDAP_DEBUG_TRACE,
493 "<= bdb_approx_candidates: (%s) no keys (%s)\n",
494 prefix.bv_val, ava->aa_desc->ad_cname.bv_val, 0 );
498 for ( i= 0; keys[i].bv_val != NULL; i++ ) {
499 rc = bdb_key_read( op->o_bd, db, NULL, &keys[i], tmp, NULL, 0 );
501 if( rc == DB_NOTFOUND ) {
505 } else if( rc != LDAP_SUCCESS ) {
506 Debug( LDAP_DEBUG_TRACE,
507 "<= bdb_approx_candidates: (%s) "
508 "key read failed (%d)\n",
509 ava->aa_desc->ad_cname.bv_val, rc, 0 );
513 if( BDB_IDL_IS_ZERO( tmp ) ) {
514 Debug( LDAP_DEBUG_TRACE,
515 "<= bdb_approx_candidates: (%s) NULL\n",
516 ava->aa_desc->ad_cname.bv_val, 0, 0 );
522 BDB_IDL_CPY( ids, tmp );
524 bdb_idl_intersection( ids, tmp );
527 if( BDB_IDL_IS_ZERO( ids ) )
531 ber_bvarray_free_x( keys, op->o_tmpmemctx );
533 Debug( LDAP_DEBUG_TRACE, "<= bdb_approx_candidates %ld, first=%ld, last=%ld\n",
535 (long) BDB_IDL_FIRST(ids),
536 (long) BDB_IDL_LAST(ids) );
541 substring_candidates(
543 SubstringsAssertion *sub,
547 struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
552 struct berval prefix = {0, NULL};
553 struct berval *keys = NULL;
556 Debug( LDAP_DEBUG_TRACE, "=> bdb_substring_candidates (%s)\n",
557 sub->sa_desc->ad_cname.bv_val, 0, 0 );
559 BDB_IDL_ALL( bdb, ids );
561 rc = bdb_index_param( op->o_bd, sub->sa_desc, LDAP_FILTER_SUBSTRINGS,
562 &db, &mask, &prefix );
564 if( rc != LDAP_SUCCESS ) {
565 Debug( LDAP_DEBUG_ANY,
566 "<= bdb_substring_candidates: (%s) "
567 "index_param failed (%d)\n",
568 sub->sa_desc->ad_cname.bv_val, rc, 0 );
573 Debug( LDAP_DEBUG_ANY,
574 "<= bdb_substring_candidates: (%s) not indexed\n",
575 sub->sa_desc->ad_cname.bv_val, 0, 0 );
579 mr = sub->sa_desc->ad_type->sat_substr;
585 if( !mr->smr_filter ) {
589 rc = (mr->smr_filter)(
590 LDAP_FILTER_SUBSTRINGS,
592 sub->sa_desc->ad_type->sat_syntax,
596 &keys, op->o_tmpmemctx );
598 if( rc != LDAP_SUCCESS ) {
599 Debug( LDAP_DEBUG_TRACE,
600 "<= bdb_substring_candidates: (%s) "
601 "MR filter failed (%d)\n",
602 sub->sa_desc->ad_cname.bv_val, rc, 0 );
607 Debug( LDAP_DEBUG_TRACE,
608 "<= bdb_substring_candidates: (0x%04lx) no keys (%s)\n",
609 mask, sub->sa_desc->ad_cname.bv_val, 0 );
613 for ( i= 0; keys[i].bv_val != NULL; i++ ) {
614 rc = bdb_key_read( op->o_bd, db, NULL, &keys[i], tmp, NULL, 0 );
616 if( rc == DB_NOTFOUND ) {
620 } else if( rc != LDAP_SUCCESS ) {
621 Debug( LDAP_DEBUG_TRACE,
622 "<= bdb_substring_candidates: (%s) "
623 "key read failed (%d)\n",
624 sub->sa_desc->ad_cname.bv_val, rc, 0 );
628 if( BDB_IDL_IS_ZERO( tmp ) ) {
629 Debug( LDAP_DEBUG_TRACE,
630 "<= bdb_substring_candidates: (%s) NULL\n",
631 sub->sa_desc->ad_cname.bv_val, 0, 0 );
637 BDB_IDL_CPY( ids, tmp );
639 bdb_idl_intersection( ids, tmp );
642 if( BDB_IDL_IS_ZERO( ids ) )
646 ber_bvarray_free_x( keys, op->o_tmpmemctx );
648 Debug( LDAP_DEBUG_TRACE, "<= bdb_substring_candidates: %ld, first=%ld, last=%ld\n",
650 (long) BDB_IDL_FIRST(ids),
651 (long) BDB_IDL_LAST(ids) );
656 inequality_candidates(
658 AttributeAssertion *ava,
663 struct bdb_info *bdb = (struct bdb_info *) op->o_bd->be_private;
668 struct berval prefix = {0, NULL};
669 struct berval *keys = NULL;
673 Debug( LDAP_DEBUG_TRACE, "=> bdb_inequality_candidates (%s)\n",
674 ava->aa_desc->ad_cname.bv_val, 0, 0 );
676 BDB_IDL_ALL( bdb, ids );
678 rc = bdb_index_param( op->o_bd, ava->aa_desc, LDAP_FILTER_EQUALITY,
679 &db, &mask, &prefix );
681 if( rc != LDAP_SUCCESS ) {
682 Debug( LDAP_DEBUG_ANY,
683 "<= bdb_inequality_candidates: (%s) "
684 "index_param failed (%d)\n",
685 ava->aa_desc->ad_cname.bv_val, rc, 0 );
690 Debug( LDAP_DEBUG_ANY,
691 "<= bdb_inequality_candidates: (%s) not indexed\n",
692 ava->aa_desc->ad_cname.bv_val, 0, 0 );
696 mr = ava->aa_desc->ad_type->sat_equality;
701 if( !mr->smr_filter ) {
705 rc = (mr->smr_filter)(
706 LDAP_FILTER_EQUALITY,
708 ava->aa_desc->ad_type->sat_syntax,
712 &keys, op->o_tmpmemctx );
714 if( rc != LDAP_SUCCESS ) {
715 Debug( LDAP_DEBUG_TRACE,
716 "<= bdb_inequality_candidates: (%s, %s) "
717 "MR filter failed (%d)\n",
718 prefix.bv_val, ava->aa_desc->ad_cname.bv_val, rc );
723 Debug( LDAP_DEBUG_TRACE,
724 "<= bdb_inequality_candidates: (%s) no keys\n",
725 ava->aa_desc->ad_cname.bv_val, 0, 0 );
731 rc = bdb_key_read( op->o_bd, db, NULL, &keys[0], tmp, &cursor, gtorlt );
733 if( rc == DB_NOTFOUND ) {
736 } else if( rc != LDAP_SUCCESS ) {
737 Debug( LDAP_DEBUG_TRACE,
738 "<= bdb_inequality_candidates: (%s) "
739 "key read failed (%d)\n",
740 ava->aa_desc->ad_cname.bv_val, rc, 0 );
744 if( BDB_IDL_IS_ZERO( tmp ) ) {
745 Debug( LDAP_DEBUG_TRACE,
746 "<= bdb_inequality_candidates: (%s) NULL\n",
747 ava->aa_desc->ad_cname.bv_val, 0, 0 );
751 bdb_idl_union( ids, tmp );
753 if( BDB_IDL_IS_ZERO( ids ) )
757 ber_bvarray_free_x( keys, op->o_tmpmemctx );
759 Debug( LDAP_DEBUG_TRACE,
760 "<= bdb_inequality_candidates: id=%ld, first=%ld, last=%ld\n",
762 (long) BDB_IDL_FIRST(ids),
763 (long) BDB_IDL_LAST(ids) );