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