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