]> git.sur5r.net Git - openldap/blob - servers/slapd/back-bdb/filterindex.c
Fix pkiUser
[openldap] / servers / slapd / back-bdb / filterindex.c
1 /* filterindex.c - generate the list of candidate entries from a filter */
2 /* $OpenLDAP$ */
3 /*
4  * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
5  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
6  */
7
8 #include "portable.h"
9
10 #include <stdio.h>
11 #include <ac/string.h>
12
13 #include "back-bdb.h"
14 #include "idl.h"
15
16 static int presence_candidates(
17         Backend *be,
18         AttributeDescription *desc,
19         ID *ids );
20
21 static int equality_candidates(
22         Backend *be,
23         AttributeAssertion *ava,
24         ID *ids,
25         ID *tmp );
26 static int approx_candidates(
27         Backend *be,
28         AttributeAssertion *ava,
29         ID *ids,
30         ID *tmp );
31 static int substring_candidates(
32         Backend *be,
33         SubstringsAssertion *sub,
34         ID *ids,
35         ID *tmp );
36
37 static int list_candidates(
38         Backend *be,
39         Filter *flist,
40         int ftype,
41         ID *ids,
42         ID *tmp,
43         ID *stack );
44
45 int
46 bdb_filter_candidates(
47         Backend *be,
48         Filter  *f,
49         ID *ids,
50         ID *tmp,
51         ID *stack )
52 {
53         int rc = -1;
54 #ifdef NEW_LOGGING
55         LDAP_LOG (( "filterindex", LDAP_LEVEL_ENTRY, "=> bdb_filter_candidates\n"));
56 #else
57         Debug( LDAP_DEBUG_FILTER, "=> bdb_filter_candidates\n", 0, 0, 0 );
58 #endif
59
60         switch ( f->f_choice ) {
61         case SLAPD_FILTER_DN_ONE:
62 #ifdef NEW_LOGGING
63                 LDAP_LOG (( "filterindex", LDAP_LEVEL_ARGS, "=> bdb_filter_candidates: \tDN ONE\n"));
64 #else
65                 Debug( LDAP_DEBUG_FILTER, "\tDN ONE\n", 0, 0, 0 );
66 #endif
67                 rc = bdb_dn2idl( be, f->f_dn, DN_ONE_PREFIX, ids );
68                 if( rc == DB_NOTFOUND ) {
69                         BDB_IDL_ZERO( ids );
70                         rc = 0;
71                 }
72                 break;
73
74         case SLAPD_FILTER_DN_SUBTREE:
75 #ifdef NEW_LOGGING
76                 LDAP_LOG (( "filterindex", LDAP_LEVEL_ARGS, "=> bdb_filter_candidates: \tDN SUBTREE\n"));
77 #else
78                 Debug( LDAP_DEBUG_FILTER, "\tDN SUBTREE\n", 0, 0, 0 );
79 #endif
80                 rc = bdb_dn2idl( be, f->f_dn, DN_SUBTREE_PREFIX, ids );
81                 break;
82
83         case LDAP_FILTER_PRESENT:
84 #ifdef NEW_LOGGING
85                 LDAP_LOG (( "filterindex", LDAP_LEVEL_ARGS, "=> bdb_filter_candidates: \tPRESENT\n"));
86 #else
87                 Debug( LDAP_DEBUG_FILTER, "\tPRESENT\n", 0, 0, 0 );
88 #endif
89                 rc = presence_candidates( be, f->f_desc, ids );
90                 break;
91
92         case LDAP_FILTER_EQUALITY:
93 #ifdef NEW_LOGGING
94                 LDAP_LOG (( "filterindex", LDAP_LEVEL_ARGS, "=> bdb_filter_candidates: \tEQUALITY\n"));
95 #else
96                 Debug( LDAP_DEBUG_FILTER, "\tEQUALITY\n", 0, 0, 0 );
97 #endif
98                 rc = equality_candidates( be, f->f_ava, ids, tmp );
99                 break;
100
101         case LDAP_FILTER_APPROX:
102 #ifdef NEW_LOGGING
103                 LDAP_LOG (( "filterindex", LDAP_LEVEL_ARGS, "=> bdb_filter_candidates: \tAPPROX\n"));
104 #else
105                 Debug( LDAP_DEBUG_FILTER, "\tAPPROX\n", 0, 0, 0 );
106 #endif
107                 rc = approx_candidates( be, f->f_ava, ids, tmp );
108                 break;
109
110         case LDAP_FILTER_SUBSTRINGS:
111 #ifdef NEW_LOGGING
112                 LDAP_LOG (( "filterindex", LDAP_LEVEL_ARGS, "=> bdb_filter_candidates: \tSUBSTRINGS\n"));
113 #else
114                 Debug( LDAP_DEBUG_FILTER, "\tSUBSTRINGS\n", 0, 0, 0 );
115 #endif
116                 rc = substring_candidates( be, f->f_sub, ids, tmp );
117                 break;
118
119         case LDAP_FILTER_GE:
120                 /* no GE index, use pres */
121 #ifdef NEW_LOGGING
122                 LDAP_LOG (( "filterindex", LDAP_LEVEL_ARGS, "=> bdb_filter_candidates: \tGE\n"));
123 #else
124                 Debug( LDAP_DEBUG_FILTER, "\tGE\n", 0, 0, 0 );
125 #endif
126                 rc = presence_candidates( be, f->f_ava->aa_desc, ids );
127                 break;
128
129         case LDAP_FILTER_LE:
130                 /* no LE index, use pres */
131 #ifdef NEW_LOGGING
132                 LDAP_LOG (( "filterindex", LDAP_LEVEL_ARGS, "=> bdb_filter_candidates: \tLE\n"));
133 #else
134                 Debug( LDAP_DEBUG_FILTER, "\tLE\n", 0, 0, 0 );
135 #endif
136                 rc = presence_candidates( be, f->f_ava->aa_desc, ids );
137                 break;
138
139         case LDAP_FILTER_NOT:
140                 /* no indexing to support NOT filters */
141 #ifdef NEW_LOGGING
142                 LDAP_LOG (( "filterindex", LDAP_LEVEL_ARGS, "=> bdb_filter_candidates: \tNOT\n"));
143 #else
144                 Debug( LDAP_DEBUG_FILTER, "\tNOT\n", 0, 0, 0 );
145 #endif
146                 break;
147
148         case LDAP_FILTER_AND:
149 #ifdef NEW_LOGGING
150                 LDAP_LOG (( "filterindex", LDAP_LEVEL_ARGS, "=> bdb_filter_candidates: \tAND\n"));
151 #else
152                 Debug( LDAP_DEBUG_FILTER, "\tAND\n", 0, 0, 0 );
153 #endif
154                 rc = list_candidates( be, 
155                         f->f_and, LDAP_FILTER_AND, ids, tmp, stack );
156                 break;
157
158         case LDAP_FILTER_OR:
159 #ifdef NEW_LOGGING
160                 LDAP_LOG (( "filterindex", LDAP_LEVEL_ARGS, "=> bdb_filter_candidates: \tOR\n"));
161 #else
162                 Debug( LDAP_DEBUG_FILTER, "\tOR\n", 0, 0, 0 );
163 #endif
164                 rc = list_candidates( be, 
165                         f->f_or, LDAP_FILTER_OR, ids, tmp, stack );
166                 break;
167
168         default:
169 #ifdef NEW_LOGGING
170                 LDAP_LOG (( "filterindex", LDAP_LEVEL_ARGS, "=> bdb_filter_candidates: \tUNKNOWN\n"));
171 #else
172                 Debug( LDAP_DEBUG_FILTER, "\tUNKNOWN %lu\n",
173                         (unsigned long) f->f_choice, 0, 0 );
174 #endif
175         }
176
177 #ifdef NEW_LOGGING
178         LDAP_LOG (( "filterindex", LDAP_LEVEL_RESULTS, "=> bdb_filter_candidates: id=%ld first=%ld last=%ld\n", (long) ids[0], (long) BDB_IDL_FIRST( ids ), (long) BDB_IDL_LAST( ids ) ));
179 #else
180         Debug( LDAP_DEBUG_FILTER,
181                 "<= bdb_filter_candidates: id=%ld first=%ld last=%ld\n",
182                 (long) ids[0],
183                 (long) BDB_IDL_FIRST( ids ),
184                 (long) BDB_IDL_LAST( ids ) );
185 #endif
186
187         return rc;
188 }
189
190 static int
191 list_candidates(
192         Backend *be,
193         Filter  *flist,
194         int             ftype,
195         ID *ids,
196         ID *tmp,
197         ID *save )
198 {
199         struct bdb_info *bdb = (struct bdb_info *) be->be_private;
200         int rc = 0;
201         Filter  *f;
202
203 #ifdef NEW_LOGGING
204         LDAP_LOG (( "filterindex", LDAP_LEVEL_ARGS, "=> bdb_list_candidates: 0x%x\n", ftype));
205 #else
206         Debug( LDAP_DEBUG_FILTER, "=> bdb_list_candidates 0x%x\n", ftype, 0, 0 );
207 #endif
208
209         if ( ftype == LDAP_FILTER_OR ) {
210                 BDB_IDL_ALL( bdb, save );
211                 BDB_IDL_ZERO( ids );
212         } else {
213                 BDB_IDL_CPY( save, ids );
214         }
215
216         for ( f = flist; f != NULL; f = f->f_next ) {
217                 rc = bdb_filter_candidates( be, f, save, tmp,
218                         save+BDB_IDL_UM_SIZE );
219
220                 if ( rc != 0 ) {
221                         if ( ftype == LDAP_FILTER_AND ) {
222                                 rc = 0;
223                                 continue;
224                         }
225                         break;
226                 }
227                 
228                 if ( ftype == LDAP_FILTER_AND ) {
229                         bdb_idl_intersection( ids, save );
230                         if( BDB_IDL_IS_ZERO( ids ) )
231                                 break;
232                 } else {
233                         bdb_idl_union( ids, save );
234                         BDB_IDL_ALL( bdb, save );
235                 }
236         }
237
238         if( rc ) {
239 #ifdef NEW_LOGGING
240                 LDAP_LOG (( "filterindex", LDAP_LEVEL_RESULTS, "<= bdb_list_candidates: id=%ld first=%ld last=%ld\n", (long) ids[0], (long) BDB_IDL_FIRST( ids ), (long) BDB_IDL_LAST( ids ) ));
241 #else
242                 Debug( LDAP_DEBUG_FILTER,
243                         "<= bdb_list_candidates: id=%ld first=%ld last=%ld\n",
244                         (long) ids[0],
245                         (long) BDB_IDL_FIRST(ids),
246                         (long) BDB_IDL_LAST(ids) );
247 #endif
248
249         } else {
250 #ifdef NEW_LOGGING
251                 LDAP_LOG (( "filterindex", LDAP_LEVEL_ARGS, "<= bdb_list_candidates: rc=%d\n", rc));
252 #else
253                 Debug( LDAP_DEBUG_FILTER,
254                         "<= bdb_list_candidates: undefined rc=%d\n",
255                         rc, 0, 0 );
256 #endif
257         }
258
259         return rc;
260 }
261
262 static int
263 presence_candidates(
264         Backend *be,
265         AttributeDescription *desc,
266         ID *ids )
267 {
268         struct bdb_info *bdb = (struct bdb_info *) be->be_private;
269         DB *db;
270         int rc;
271         slap_mask_t mask;
272         struct berval prefix = {0};
273
274 #ifdef NEW_LOGGING
275         LDAP_LOG (( "filterindex", LDAP_LEVEL_ENTRY, "=> bdb_presence_candidates\n"));
276 #else
277         Debug( LDAP_DEBUG_TRACE, "=> bdb_presence_candidates\n", 0, 0, 0 );
278 #endif
279
280         if( desc == slap_schema.si_ad_objectClass ) {
281                 BDB_IDL_ALL( bdb, ids );
282                 return 0;
283         }
284
285         rc = bdb_index_param( be, desc, LDAP_FILTER_PRESENT,
286                 &db, &mask, &prefix );
287
288         if( rc != LDAP_SUCCESS ) {
289 #ifdef NEW_LOGGING
290                 LDAP_LOG (( "filterindex", LDAP_LEVEL_RESULTS, "=> bdb_presence_candidates: index_parm returned=%d\n", rc ));
291 #else
292                 Debug( LDAP_DEBUG_TRACE,
293                         "<= bdb_presence_candidates: index_param returned=%d\n",
294                         rc, 0, 0 );
295 #endif
296                 return 0;
297         }
298
299         if( db == NULL ) {
300                 /* not indexed */
301 #ifdef NEW_LOGGING
302                 LDAP_LOG (( "filterindex", LDAP_LEVEL_RESULTS, "<= bdb_presence_candidates: not indexed\n" ));
303 #else
304                 Debug( LDAP_DEBUG_TRACE,
305                         "<= bdb_presence_candidates: not indexed\n",
306                         0, 0, 0 );
307 #endif
308                 return 0;
309         }
310
311         if( prefix.bv_val == NULL ) {
312 #ifdef NEW_LOGGING
313                 LDAP_LOG (( "filterindex", LDAP_LEVEL_RESULTS, "<= bdb_presence_candidates: no prefix\n" ));
314 #else
315                 Debug( LDAP_DEBUG_TRACE,
316                         "<= bdb_presence_candidates: no prefix\n",
317                         0, 0, 0 );
318 #endif
319                 return 0;
320         }
321
322         rc = bdb_key_read( be, db, NULL, &prefix, ids );
323
324         if( rc == DB_NOTFOUND ) {
325                 BDB_IDL_ZERO( ids );
326                 rc = 0;
327         } else if( rc != LDAP_SUCCESS ) {
328 #ifdef NEW_LOGGING
329                 LDAP_LOG (( "filterindex", LDAP_LEVEL_RESULTS, "<= bdb_presence_candidates: key read failed (%d)\n", rc ));
330 #else
331                 Debug( LDAP_DEBUG_TRACE,
332                         "<= bdb_presense_candidates: key read failed (%d)\n",
333                         rc, 0, 0 );
334 #endif
335                 goto done;
336         }
337
338 #ifdef NEW_LOGGING
339         LDAP_LOG (( "filterindex", LDAP_LEVEL_RESULTS, "<= bdb_presence_candidates: id=%ld first=%ld last=%ld\n", (long) ids[0], (long) BDB_IDL_FIRST( ids ), (long) BDB_IDL_LAST( ids ) ));
340 #else
341         Debug(LDAP_DEBUG_TRACE,
342                 "<= bdb_presence_candidates: id=%ld first=%ld last=%ld\n",
343                 (long) ids[0],
344                 (long) BDB_IDL_FIRST(ids),
345                 (long) BDB_IDL_LAST(ids) );
346 #endif
347
348 done:
349         return rc;
350 }
351
352 static int
353 equality_candidates(
354         Backend *be,
355         AttributeAssertion *ava,
356         ID *ids,
357         ID *tmp )
358 {
359         DB      *db;
360         int i;
361         int rc;
362         slap_mask_t mask;
363         struct berval prefix = {0};
364         struct berval *keys = NULL;
365         MatchingRule *mr;
366
367 #ifdef NEW_LOGGING
368         LDAP_LOG (( "filterindex", LDAP_LEVEL_ENTRY, "=> equality_candidates\n"));
369 #else
370         Debug( LDAP_DEBUG_TRACE, "=> bdb_equality_candidates\n", 0, 0, 0 );
371 #endif
372
373         rc = bdb_index_param( be, ava->aa_desc, LDAP_FILTER_EQUALITY,
374                 &db, &mask, &prefix );
375
376         if( rc != LDAP_SUCCESS ) {
377 #ifdef NEW_LOGGING
378                 LDAP_LOG (( "filterindex", LDAP_LEVEL_RESULTS, "=> bdb_equality_candidates: index_param failed (%d)\n", rc));
379 #else
380                 Debug( LDAP_DEBUG_ANY,
381                         "<= bdb_equality_candidates: index_param failed (%d)\n",
382                         rc, 0, 0 );
383 #endif
384                 return rc;
385         }
386
387         if ( db == NULL ) {
388 #ifdef NEW_LOGGING
389                 LDAP_LOG (( "filterindex", LDAP_LEVEL_RESULTS, "=> bdb_equality_candidates: not indexed\n"));
390 #else
391                 Debug( LDAP_DEBUG_ANY,
392                         "<= bdb_equality_candidates: not indexed\n", 0, 0, 0 );
393 #endif
394                 return -1;
395         }
396
397         mr = ava->aa_desc->ad_type->sat_equality;
398         if( !mr ) {
399                 return -1;
400         }
401
402         if( !mr->smr_filter ) {
403                 return -1;
404         }
405
406         rc = (mr->smr_filter)(
407                 LDAP_FILTER_EQUALITY,
408                 mask,
409                 ava->aa_desc->ad_type->sat_syntax,
410                 mr,
411                 &prefix,
412                 &ava->aa_value,
413                 &keys );
414
415         if( rc != LDAP_SUCCESS ) {
416 #ifdef NEW_LOGGING
417                 LDAP_LOG (( "filterindex", LDAP_LEVEL_RESULTS, "=> bdb_equality_candidates: MR filter failed (%d)\n", rc));
418 #else
419                 Debug( LDAP_DEBUG_TRACE,
420                         "<= bdb_equality_candidates: MR filter failed (%d)\n",
421                         rc, 0, 0 );
422 #endif
423                 return rc;
424         }
425
426         if( keys == NULL ) {
427 #ifdef NEW_LOGGING
428                 LDAP_LOG (( "filterindex", LDAP_LEVEL_RESULTS, "=> bdb_equality_candidates: no keys\n"));
429 #else
430                 Debug( LDAP_DEBUG_TRACE,
431                         "<= bdb_equality_candidates: no keys\n",
432                         0, 0, 0 );
433 #endif
434                 return 0;
435         }
436
437         for ( i= 0; keys[i].bv_val != NULL; i++ ) {
438                 rc = bdb_key_read( be, db, NULL, &keys[i], tmp );
439
440                 if( rc == DB_NOTFOUND ) {
441                         BDB_IDL_ZERO( ids );
442                         rc = 0;
443                 } else if( rc != LDAP_SUCCESS ) {
444 #ifdef NEW_LOGGING
445                         LDAP_LOG (( "filterindex", LDAP_LEVEL_RESULTS, "<= bdb_equality_candidates: key read failed (%d)\n", rc));
446 #else
447                         Debug( LDAP_DEBUG_TRACE,
448                                 "<= bdb_equality_candidates key read failed (%d)\n",
449                                 rc, 0, 0 );
450 #endif
451                         break;
452                 }
453
454                 if( BDB_IDL_IS_ZERO( tmp ) ) {
455 #ifdef NEW_LOGGING
456                         LDAP_LOG (( "filterindex", LDAP_LEVEL_RESULTS, "=> bdb_equality_candidates: NULL\n"));
457 #else
458                         Debug( LDAP_DEBUG_TRACE,
459                                 "<= bdb_equality_candidates NULL\n",
460                                 0, 0, 0 );
461 #endif
462                         BDB_IDL_ZERO( ids );
463                         break;
464                 }
465
466                 bdb_idl_intersection( ids, tmp );
467
468                 if( BDB_IDL_IS_ZERO( ids ) )
469                         break;
470         }
471
472         ber_bvarray_free( keys );
473
474 #ifdef NEW_LOGGING
475         LDAP_LOG (( "filterindex", LDAP_LEVEL_RESULTS, "<= bdb_equality_candidates: id=%ld first=%ld last=%ld\n", (long) ids[0], (long) BDB_IDL_FIRST( ids ), (long) BDB_IDL_LAST( ids ) ));
476 #else
477         Debug( LDAP_DEBUG_TRACE,
478                 "<= bdb_equality_candidates id=%ld, first=%ld, last=%ld\n",
479                 (long) ids[0],
480                 (long) BDB_IDL_FIRST(ids),
481                 (long) BDB_IDL_LAST(ids) );
482 #endif
483         return( rc );
484 }
485
486
487 static int
488 approx_candidates(
489         Backend *be,
490         AttributeAssertion *ava,
491         ID *ids,
492         ID *tmp )
493 {
494         DB      *db;
495         int i;
496         int rc;
497         slap_mask_t mask;
498         struct berval prefix = {0};
499         struct berval *keys = NULL;
500         MatchingRule *mr;
501
502 #ifdef NEW_LOGGING
503         LDAP_LOG (( "filterindex", LDAP_LEVEL_ENTRY, "=> bdb_approx_candidates\n"));
504 #else
505         Debug( LDAP_DEBUG_TRACE, "=> bdb_approx_candidates\n", 0, 0, 0 );
506 #endif
507
508         rc = bdb_index_param( be, ava->aa_desc, LDAP_FILTER_APPROX,
509                 &db, &mask, &prefix );
510
511         if( rc != LDAP_SUCCESS ) {
512 #ifdef NEW_LOGGING
513                 LDAP_LOG (( "filterindex", LDAP_LEVEL_RESULTS, "<= bdb_approx_candidates: index_param failed (%d)\n", rc ));
514 #else
515                 Debug( LDAP_DEBUG_ANY,
516                         "<= bdb_approx_candidates: index_param failed (%d)\n",
517                         rc, 0, 0 );
518 #endif
519                 return rc;
520         }
521
522         if ( db == NULL ) {
523 #ifdef NEW_LOGGING
524                 LDAP_LOG (( "filterindex", LDAP_LEVEL_RESULTS, "<= bdb_approx_candidates: not indexed\n" ));
525 #else
526                 Debug( LDAP_DEBUG_ANY,
527                         "<= bdb_approx_candidates: not indexed\n", 0, 0, 0 );
528 #endif
529                 return -1;
530         }
531
532         mr = ava->aa_desc->ad_type->sat_approx;
533         if( !mr ) {
534                 /* no approx matching rule, try equality matching rule */
535                 mr = ava->aa_desc->ad_type->sat_equality;
536         }
537
538         if( !mr ) {
539                 return -1;
540         }
541
542         if( !mr->smr_filter ) {
543                 return -1;
544         }
545
546         rc = (mr->smr_filter)(
547                 LDAP_FILTER_APPROX,
548                 mask,
549                 ava->aa_desc->ad_type->sat_syntax,
550                 mr,
551                 &prefix,
552                 &ava->aa_value,
553                 &keys );
554
555         if( rc != LDAP_SUCCESS ) {
556 #ifdef NEW_LOGGING
557                 LDAP_LOG (( "filterindex", LDAP_LEVEL_RESULTS, "<= bdb_approx_candidates: MR filter failed (%d)\n", rc ));
558 #else
559                 Debug( LDAP_DEBUG_TRACE,
560                         "<= bdb_approx_candidates: (%s) MR filter failed (%d)\n",
561                         prefix.bv_val, rc, 0 );
562 #endif
563                 return rc;
564         }
565
566         if( keys == NULL ) {
567 #ifdef NEW_LOGGING
568                 LDAP_LOG (( "filterindex", LDAP_LEVEL_RESULTS, "<= bdb_approx_candidates: no keys (%s)\n", prefix.bv_val ));
569 #else
570                 Debug( LDAP_DEBUG_TRACE,
571                         "<= bdb_approx_candidates: no keys (%s)\n",
572                         prefix.bv_val, 0, 0 );
573 #endif
574                 return 0;
575         }
576
577         for ( i= 0; keys[i].bv_val != NULL; i++ ) {
578                 rc = bdb_key_read( be, db, NULL, &keys[i], tmp );
579
580                 if( rc == DB_NOTFOUND ) {
581                         BDB_IDL_ZERO( ids );
582                         rc = 0;
583                         break;
584                 } else if( rc != LDAP_SUCCESS ) {
585 #ifdef NEW_LOGGING
586                 LDAP_LOG (( "filterindex", LDAP_LEVEL_RESULTS, "<= bdb_approx_candidates: key read failed (%d)\n", rc ));
587 #else
588                         Debug( LDAP_DEBUG_TRACE, "<= bdb_approx_candidates key read failed (%d)\n",
589                                 rc, 0, 0 );
590 #endif
591                         break;
592                 }
593
594                 if( BDB_IDL_IS_ZERO( tmp ) ) {
595 #ifdef NEW_LOGGING
596                         LDAP_LOG (( "filterindex", LDAP_LEVEL_RESULTS, "<= bdb_approx_candidates: NULL\n" ));
597 #else
598                         Debug( LDAP_DEBUG_TRACE, "<= bdb_approx_candidates NULL\n",
599                                 0, 0, 0 );
600 #endif
601                         BDB_IDL_ZERO( ids );
602                         break;
603                 }
604
605                 bdb_idl_intersection( ids, tmp );
606
607                 if( BDB_IDL_IS_ZERO( ids ) )
608                         break;
609         }
610
611         ber_bvarray_free( keys );
612
613 #ifdef NEW_LOGGING
614         LDAP_LOG (( "filterindex", LDAP_LEVEL_RESULTS, "<= bdb_approx_candidates: id=%ld first=%ld last=%ld\n", (long) ids[0], (long) BDB_IDL_FIRST( ids ), (long) BDB_IDL_LAST( ids ) ));
615 #else
616         Debug( LDAP_DEBUG_TRACE, "<= bdb_approx_candidates %ld, first=%ld, last=%ld\n",
617                 (long) ids[0],
618                 (long) BDB_IDL_FIRST(ids),
619                 (long) BDB_IDL_LAST(ids) );
620 #endif
621         return( rc );
622 }
623
624 static int
625 substring_candidates(
626         Backend *be,
627         SubstringsAssertion     *sub,
628         ID *ids,
629         ID *tmp )
630 {
631         DB      *db;
632         int i;
633         int rc;
634         slap_mask_t mask;
635         struct berval prefix = {0};
636         struct berval *keys = NULL;
637         MatchingRule *mr;
638
639 #ifdef NEW_LOGGING
640         LDAP_LOG (( "filterindex", LDAP_LEVEL_ENTRY, "=> bdb_substring_candidates\n"));
641 #else
642         Debug( LDAP_DEBUG_TRACE, "=> bdb_substring_candidates\n", 0, 0, 0 );
643 #endif
644
645         rc = bdb_index_param( be, sub->sa_desc, LDAP_FILTER_SUBSTRINGS,
646                 &db, &mask, &prefix );
647
648         if( rc != LDAP_SUCCESS ) {
649 #ifdef NEW_LOGGING
650                 LDAP_LOG (( "filterindex", LDAP_LEVEL_RESULTS, "<= bdb_substring_candidates: index_param failed (%d)\n", rc ));
651 #else
652                 Debug( LDAP_DEBUG_ANY,
653                         "<= bdb_substring_candidates: index_param failed (%d)\n",
654                         rc, 0, 0 );
655 #endif
656                 return rc;
657         }
658
659         if ( db == NULL ) {
660 #ifdef NEW_LOGGING
661                 LDAP_LOG (( "filterindex", LDAP_LEVEL_RESULTS, "<= bdb_substring_candidates: not indexed\n"));
662 #else
663                 Debug( LDAP_DEBUG_ANY,
664                         "<= bdb_substring_candidates not indexed\n",
665                         0, 0, 0 );
666 #endif
667                 return -1;
668         }
669
670         mr = sub->sa_desc->ad_type->sat_substr;
671
672         if( !mr ) {
673                 return -1;
674         }
675
676         if( !mr->smr_filter ) {
677                 return -1;
678         }
679
680         rc = (mr->smr_filter)(
681                 LDAP_FILTER_SUBSTRINGS,
682                 mask,
683                 sub->sa_desc->ad_type->sat_syntax,
684                 mr,
685                 &prefix,
686                 sub,
687                 &keys );
688
689         if( rc != LDAP_SUCCESS ) {
690 #ifdef NEW_LOGGING
691                 LDAP_LOG (( "filterindex", LDAP_LEVEL_RESULTS, "<= bdb_substring_candidates: (%s) MR filter failed (%d)\n", sub->sa_desc->ad_cname.bv_val, rc ));
692 #else
693                 Debug( LDAP_DEBUG_TRACE,
694                         "<= bdb_substring_candidates: (%s) MR filter failed (%d)\n",
695                         sub->sa_desc->ad_cname.bv_val, rc, 0 );
696 #endif
697                 return rc;
698         }
699
700         if( keys == NULL ) {
701 #ifdef NEW_LOGGING
702                 LDAP_LOG (( "filterindex", LDAP_LEVEL_RESULTS, "<= bdb_substring_candidates: (%s) MR filter failed (%d)\n", mask, sub->sa_desc->ad_cname.bv_val ));
703 #else
704                 Debug( LDAP_DEBUG_TRACE,
705                         "<= bdb_substring_candidates: (0x%04lx) no keys (%s)\n",
706                         mask, sub->sa_desc->ad_cname.bv_val, 0 );
707 #endif
708                 return 0;
709         }
710
711         for ( i= 0; keys[i].bv_val != NULL; i++ ) {
712                 rc = bdb_key_read( be, db, NULL, &keys[i], tmp );
713
714                 if( rc == DB_NOTFOUND ) {
715                         BDB_IDL_ZERO( ids );
716                         rc = 0;
717                         break;
718                 } else if( rc != LDAP_SUCCESS ) {
719 #ifdef NEW_LOGGING
720                         LDAP_LOG (( "filterindex", LDAP_LEVEL_RESULTS, "<= bdb_substring_candidates: key read failed (%d)\n", rc));
721 #else
722                         Debug( LDAP_DEBUG_TRACE, "<= bdb_substring_candidates key read failed (%d)\n",
723                                 rc, 0, 0 );
724 #endif
725                         break;
726                 }
727
728                 if( BDB_IDL_IS_ZERO( tmp ) ) {
729 #ifdef NEW_LOGGING
730                         LDAP_LOG (( "filterindex", LDAP_LEVEL_RESULTS, "<= bdb_substring_candidates: NULL \n" ));
731 #else
732                         Debug( LDAP_DEBUG_TRACE, "<= bdb_substring_candidates NULL\n",
733                                 0, 0, 0 );
734 #endif
735                         BDB_IDL_ZERO( ids );
736                         break;
737                 }
738
739                 bdb_idl_intersection( ids, tmp );
740
741                 if( BDB_IDL_IS_ZERO( ids ) )
742                         break;
743         }
744
745         ber_bvarray_free( keys );
746
747 #ifdef NEW_LOGGING
748         LDAP_LOG (( "filterindex", LDAP_LEVEL_RESULTS, "<= bdb_substring_candidates: id=%ld first=%ld last=%ld\n", (long) ids[0], (long) BDB_IDL_FIRST( ids ), (long) BDB_IDL_LAST( ids ) ));
749 #else
750         Debug( LDAP_DEBUG_TRACE, "<= bdb_substring_candidates %ld, first=%ld, last=%ld\n",
751                 (long) ids[0],
752                 (long) BDB_IDL_FIRST(ids),
753                 (long) BDB_IDL_LAST(ids) );
754 #endif
755         return( 0 );
756 }
757