]> git.sur5r.net Git - openldap/blob - servers/slapd/back-ldbm/filterindex.c
79a2ee45b6ffe3d2839ae13da898cb4512406b9a
[openldap] / servers / slapd / back-ldbm / filterindex.c
1 /* filterindex.c - generate the list of candidate entries from a filter */
2 /* $OpenLDAP$ */
3 /*
4  * Copyright 1998-2003 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
12 #include <ac/socket.h>
13 #include <ac/string.h>
14
15 #include "slap.h"
16 #include "back-ldbm.h"
17
18 static ID_BLOCK *presence_candidates(
19         Operation *op,
20         AttributeDescription *desc );
21 static ID_BLOCK *equality_candidates(
22         Operation *op, AttributeAssertion *ava );
23 static ID_BLOCK *approx_candidates(
24         Operation *op, AttributeAssertion *ava );
25 static ID_BLOCK *substring_candidates(
26         Operation *op,
27         SubstringsAssertion *sub );
28 static ID_BLOCK *list_candidates(
29         Operation *op,
30         Filter *flist,
31         int ftype );
32
33 ID_BLOCK *
34 filter_candidates(
35     Operation   *op,
36     Filter      *f
37 )
38 {
39         ID_BLOCK        *result;
40
41 #ifdef NEW_LOGGING
42         LDAP_LOG( FILTER, ENTRY, "filter_candidates: enter\n", 0, 0, 0 );
43 #else
44         Debug( LDAP_DEBUG_TRACE, "=> filter_candidates\n", 0, 0, 0 );
45 #endif
46
47
48         result = NULL;
49         switch ( f->f_choice ) {
50         case SLAPD_FILTER_COMPUTED:
51                 switch( f->f_result ) {
52                 case SLAPD_COMPARE_UNDEFINED:
53                 /* This technically is not the same as FALSE, but it
54                  * certainly will produce no matches.
55                  */
56                 /* FALLTHRU */
57                 case LDAP_COMPARE_FALSE:
58                         result = NULL;
59                         break;
60                 case LDAP_COMPARE_TRUE:
61                         result = idl_allids( op->o_bd );
62                         break;
63                 }
64                 break;
65
66         case SLAPD_FILTER_DN_ONE:
67 #ifdef NEW_LOGGING
68                 LDAP_LOG( FILTER, DETAIL1, 
69                            "filter_candidates:  DN ONE (%s)\n", f->f_dn, 0, 0 );
70 #else
71                 Debug( LDAP_DEBUG_FILTER, "\tDN ONE\n", 0, 0, 0 );
72 #endif
73
74                 /* an error is treated as an empty list */
75                 if ( dn2idl( op->o_bd, f->f_dn, DN_ONE_PREFIX, &result ) != 0
76                                 && result != NULL ) {
77                         idl_free( result );
78                         result = NULL;
79                 }
80                 break;
81
82         case SLAPD_FILTER_DN_SUBTREE:
83 #ifdef NEW_LOGGING
84                 LDAP_LOG( FILTER, DETAIL1, 
85                            "filter_candidates:  DN SUBTREE (%s)\n", f->f_dn, 0, 0 );
86 #else
87                 Debug( LDAP_DEBUG_FILTER, "\tDN SUBTREE\n", 0, 0, 0 );
88 #endif
89
90                 /* an error is treated as an empty list */
91                 if ( dn2idl( op->o_bd, f->f_dn, DN_SUBTREE_PREFIX, &result ) != 0
92                                 && result != NULL ) {
93                         idl_free( result );
94                         result = NULL;
95                 }
96                 break;
97
98         case LDAP_FILTER_PRESENT:
99 #ifdef NEW_LOGGING
100                 LDAP_LOG( FILTER, DETAIL1, 
101                         "filter_candidates:  Present (%s)\n", 
102                         f->f_desc->ad_cname.bv_val, 0, 0 );
103 #else
104                 Debug( LDAP_DEBUG_FILTER, "\tPRESENT\n", 0, 0, 0 );
105 #endif
106
107                 result = presence_candidates( op, f->f_desc );
108                 break;
109
110         case LDAP_FILTER_EQUALITY:
111 #ifdef NEW_LOGGING
112                 LDAP_LOG( FILTER, DETAIL1, 
113                            "filter_candidates:  EQUALITY (%s),(%s)\n",
114                            f->f_ava->aa_desc->ad_cname.bv_val,
115                            f->f_ava->aa_value.bv_val, 0 );
116 #else
117                 Debug( LDAP_DEBUG_FILTER, "\tEQUALITY\n", 0, 0, 0 );
118 #endif
119
120                 result = equality_candidates( op, f->f_ava );
121                 break;
122
123         case LDAP_FILTER_APPROX:
124 #ifdef NEW_LOGGING
125                 LDAP_LOG( FILTER, DETAIL1, 
126                            "filter_candidates:  APPROX (%s), (%s)\n",
127                            f->f_ava->aa_desc->ad_cname.bv_val,
128                            f->f_ava->aa_value.bv_val, 0 );
129 #else
130                 Debug( LDAP_DEBUG_FILTER, "\tAPPROX\n", 0, 0, 0 );
131 #endif
132
133                 result = approx_candidates( op, f->f_ava );
134                 break;
135
136         case LDAP_FILTER_SUBSTRINGS:
137 #ifdef NEW_LOGGING
138                 LDAP_LOG( FILTER, DETAIL1,
139                            "filter_candidates:  SUBSTRINGS\n", 0, 0, 0 );
140 #else
141                 Debug( LDAP_DEBUG_FILTER, "\tSUBSTRINGS\n", 0, 0, 0 );
142 #endif
143
144                 result = substring_candidates( op, f->f_sub );
145                 break;
146
147         case LDAP_FILTER_GE:
148 #ifdef NEW_LOGGING
149                 LDAP_LOG( FILTER, DETAIL1, "filter_candidates:  GE\n", 0, 0, 0 );
150 #else
151                 Debug( LDAP_DEBUG_FILTER, "\tGE\n", 0, 0, 0 );
152 #endif
153
154                 result = presence_candidates( op, f->f_ava->aa_desc );
155                 break;
156
157         case LDAP_FILTER_LE:
158 #ifdef NEW_LOGGING
159                 LDAP_LOG( FILTER, DETAIL1, "filter_candidates:  LE\n", 0, 0, 0 );
160 #else
161                 Debug( LDAP_DEBUG_FILTER, "\tLE\n", 0, 0, 0 );
162 #endif
163
164                 result = presence_candidates( op, f->f_ava->aa_desc );
165                 break;
166
167         case LDAP_FILTER_AND:
168 #ifdef NEW_LOGGING
169                 LDAP_LOG( FILTER, DETAIL1, "filter_candidates:  AND\n", 0, 0, 0 );
170 #else
171                 Debug( LDAP_DEBUG_FILTER, "\tAND\n", 0, 0, 0 );
172 #endif
173
174                 result = list_candidates( op, f->f_and, LDAP_FILTER_AND );
175                 break;
176
177         case LDAP_FILTER_OR:
178 #ifdef NEW_LOGGING
179                 LDAP_LOG( FILTER, DETAIL1, "filter_candidates:  OR\n", 0, 0, 0 );
180 #else
181                 Debug( LDAP_DEBUG_FILTER, "\tOR\n", 0, 0, 0 );
182 #endif
183
184                 result = list_candidates( op, f->f_or, LDAP_FILTER_OR );
185                 break;
186
187         case LDAP_FILTER_NOT:
188 #ifdef NEW_LOGGING
189                 LDAP_LOG( FILTER, DETAIL1, "filter_candidates:  NOT\n", 0, 0, 0 );
190 #else
191                 Debug( LDAP_DEBUG_FILTER, "\tNOT\n", 0, 0, 0 );
192 #endif
193
194                 /*
195                  * As candidates lists may contain entries which do
196                  * not match the assertion, negation of the inner candidate
197                  * list could result in matching entries be excluded from
198                  * the returned candidate list.
199                  */
200                 result = idl_allids( op->o_bd );
201                 break;
202         default:
203 #ifdef NEW_LOGGING
204                 LDAP_LOG( FILTER, DETAIL1, "filter_candidates:  UNKNOWN\n", 0, 0, 0 );
205 #else
206                 Debug( LDAP_DEBUG_FILTER, "\tUNKNOWN\n", 0, 0, 0 );
207 #endif
208                 /* unknown filters must not return NULL, to allow
209                  * extended filter processing to be done later.
210                  */
211                 result = idl_allids( op->o_bd );
212                 break;
213         }
214
215 #ifdef NEW_LOGGING
216         LDAP_LOG( FILTER, ENTRY, 
217                 "filter_candidates: return %ld\n", 
218                 result ? ID_BLOCK_NIDS(result) : 0, 0, 0 );
219 #else
220         Debug( LDAP_DEBUG_TRACE, "<= filter_candidates %ld\n",
221             result ? ID_BLOCK_NIDS(result) : 0, 0, 0 );
222 #endif
223
224         return( result );
225 }
226
227 static ID_BLOCK *
228 presence_candidates(
229     Operation *op,
230         AttributeDescription *desc
231 )
232 {
233         ID_BLOCK        *idl;
234         DBCache *db;
235         int rc;
236         char *dbname;
237         slap_mask_t mask;
238         struct berval prefix = {0, NULL};
239
240 #ifdef NEW_LOGGING
241         LDAP_LOG( FILTER, ENTRY, "presence_candidates: enter\n", 0, 0, 0 );
242 #else
243         Debug( LDAP_DEBUG_TRACE, "=> presence_candidates\n", 0, 0, 0 );
244 #endif
245
246         idl = idl_allids( op->o_bd );
247
248         if( desc == slap_schema.si_ad_objectClass ) {
249                 return idl;
250         }
251
252         rc = index_param( op->o_bd, desc, LDAP_FILTER_PRESENT,
253                 &dbname, &mask, &prefix );
254
255         if( rc != LDAP_SUCCESS ) {
256 #ifdef NEW_LOGGING
257                 LDAP_LOG( FILTER, INFO, 
258                            "presence_candidates: index_param returned %d\n", rc, 0, 0 );
259 #else
260                 Debug( LDAP_DEBUG_TRACE,
261                     "<= presence_candidates: index_param returned=%d\n",
262                         rc, 0, 0 );
263 #endif
264
265                 return idl;
266         }
267
268         if( dbname == NULL ) {
269                 /* not indexed */
270 #ifdef NEW_LOGGING
271                 LDAP_LOG( FILTER, INFO, "presence_candidates: not indexed\n", 0, 0, 0 );
272 #else
273                 Debug( LDAP_DEBUG_TRACE,
274                     "<= presense_candidates: not indexed\n",
275                         0, 0, 0 );
276 #endif
277
278                 return idl;
279         }
280
281         db = ldbm_cache_open( op->o_bd, dbname, LDBM_SUFFIX, LDBM_WRCREAT );
282         
283         if ( db == NULL ) {
284 #ifdef NEW_LOGGING
285                 LDAP_LOG( FILTER, INFO, 
286                            "presence_candidates: db open failed (%s%s)\n",
287                            dbname, LDBM_SUFFIX, 0 );
288 #else
289                 Debug( LDAP_DEBUG_ANY,
290                     "<= presense_candidates db open failed (%s%s)\n",
291                         dbname, LDBM_SUFFIX, 0 );
292 #endif
293
294                 return idl;
295         }
296
297         if( prefix.bv_val != NULL ) {
298                 idl_free( idl );
299                 idl = NULL;
300
301                 rc = key_read( op->o_bd, db, &prefix, &idl );
302
303                 if( rc != LDAP_SUCCESS ) {
304 #ifdef NEW_LOGGING
305                         LDAP_LOG( FILTER, ERR, 
306                                    "presence_candidates: key read failed (%d)\n", rc, 0, 0 );
307 #else
308                         Debug( LDAP_DEBUG_TRACE,
309                                 "<= presense_candidates key read failed (%d)\n",
310                             rc, 0, 0 );
311 #endif
312
313
314                 } else if( idl == NULL ) {
315 #ifdef NEW_LOGGING
316                         LDAP_LOG( FILTER, DETAIL1, "presence_candidates: NULL\n", 0, 0, 0 );
317 #else
318                         Debug( LDAP_DEBUG_TRACE,
319                                 "<= presense_candidates NULL\n",
320                             0, 0, 0 );
321 #endif
322
323                 }
324         }
325
326         ldbm_cache_close( op->o_bd, db );
327
328 #ifdef NEW_LOGGING
329         LDAP_LOG( FILTER, ENTRY, 
330                 "presence_candidates:  return %ld\n", 
331                 idl ? ID_BLOCK_NIDS(idl) : 0, 0, 0 );
332 #else
333         Debug( LDAP_DEBUG_TRACE, "<= presence_candidates %ld\n",
334             idl ? ID_BLOCK_NIDS(idl) : 0, 0, 0 );
335 #endif
336
337         return( idl );
338 }
339
340 static ID_BLOCK *
341 equality_candidates(
342     Operation *op,
343         AttributeAssertion *ava
344 )
345 {
346         ID_BLOCK        *idl;
347         DBCache *db;
348         int i;
349         int rc;
350         char *dbname;
351         slap_mask_t mask;
352         struct berval prefix = {0, NULL};
353         struct berval *keys = NULL;
354         MatchingRule *mr;
355
356 #ifdef NEW_LOGGING
357         LDAP_LOG( FILTER, ENTRY, "equality_candidates: enter\n", 0, 0, 0 );
358 #else
359         Debug( LDAP_DEBUG_TRACE, "=> equality_candidates\n", 0, 0, 0 );
360 #endif
361
362
363         idl = idl_allids( op->o_bd );
364
365         rc = index_param( op->o_bd, ava->aa_desc, LDAP_FILTER_EQUALITY,
366                 &dbname, &mask, &prefix );
367
368         if( rc != LDAP_SUCCESS ) {
369 #ifdef NEW_LOGGING
370                 LDAP_LOG( FILTER, ERR, 
371                            "equality_candidates:  index_param returned %d\n", rc, 0, 0 );
372 #else
373                 Debug( LDAP_DEBUG_TRACE,
374                     "<= equality_candidates: index_param returned=%d\n",
375                         rc, 0, 0 );
376 #endif
377
378                 return idl;
379         }
380
381         if( dbname == NULL ) {
382                 /* not indexed */
383 #ifdef NEW_LOGGING
384                 LDAP_LOG( FILTER, ERR, "equality_candidates: not indexed\n", 0, 0, 0 );
385 #else
386                 Debug( LDAP_DEBUG_TRACE,
387                     "<= equality_candidates: not indexed\n",
388                         0, 0, 0 );
389 #endif
390
391                 return idl;
392         }
393
394         mr = ava->aa_desc->ad_type->sat_equality;
395         if( !mr ) {
396                 return idl;
397         }
398
399         if( !mr->smr_filter ) {
400                 return idl;
401         }
402
403         rc = (mr->smr_filter)(
404                 LDAP_FILTER_EQUALITY,
405                 mask,
406                 ava->aa_desc->ad_type->sat_syntax,
407                 mr,
408                 &prefix,
409                 &ava->aa_value,
410                 &keys, op->o_tmpmemctx );
411
412         if( rc != LDAP_SUCCESS ) {
413 #ifdef NEW_LOGGING
414                 LDAP_LOG( FILTER, ERR, 
415                            "equality_candidates: (%s%s) MR filter failed (%d\n",
416                            dbname, LDBM_SUFFIX, rc );
417 #else
418                 Debug( LDAP_DEBUG_TRACE,
419                     "<= equality_candidates: (%s%s) MR filter failed (%d)\n",
420                         dbname, LDBM_SUFFIX, rc );
421 #endif
422
423                 return idl;
424         }
425
426         if( keys == NULL ) {
427 #ifdef NEW_LOGGING
428                 LDAP_LOG( FILTER, ERR, 
429                    "equality_candidates: no keys (%s%s)\n", dbname, LDBM_SUFFIX, 0 );
430 #else
431                 Debug( LDAP_DEBUG_TRACE,
432                     "<= equality_candidates: no keys (%s%s)\n",
433                         dbname, LDBM_SUFFIX, 0 );
434 #endif
435
436                 return idl;
437         }
438
439         db = ldbm_cache_open( op->o_bd, dbname, LDBM_SUFFIX, LDBM_WRCREAT );
440         
441         if ( db == NULL ) {
442 #ifdef NEW_LOGGING
443                 LDAP_LOG( FILTER, ERR, "equality_candidates: db open failed (%s%s)\n",
444                         dbname, LDBM_SUFFIX, 0 );
445 #else
446                 Debug( LDAP_DEBUG_ANY,
447                     "<= equality_candidates db open failed (%s%s)\n",
448                         dbname, LDBM_SUFFIX, 0 );
449 #endif
450
451                 return idl;
452         }
453
454         for ( i= 0; keys[i].bv_val != NULL; i++ ) {
455                 ID_BLOCK *save;
456                 ID_BLOCK *tmp;
457
458                 rc = key_read( op->o_bd, db, &keys[i], &tmp );
459
460                 if( rc != LDAP_SUCCESS ) {
461                         idl_free( idl );
462                         idl = NULL;
463 #ifdef NEW_LOGGING
464                         LDAP_LOG( FILTER, ERR, 
465                                    "equality_candidates: key read failed (%d)\n", rc, 0, 0 );
466 #else
467                         Debug( LDAP_DEBUG_TRACE,
468                                 "<= equality_candidates key read failed (%d)\n",
469                             rc, 0, 0 );
470 #endif
471
472                         break;
473                 }
474
475                 if( tmp == NULL ) {
476                         idl_free( idl );
477                         idl = NULL;
478 #ifdef NEW_LOGGING
479                         LDAP_LOG( FILTER, INFO, "equality_candidates NULL\n", 0, 0, 0 );
480 #else
481                         Debug( LDAP_DEBUG_TRACE,
482                                 "<= equality_candidates NULL\n",
483                             0, 0, 0 );
484 #endif
485
486                         break;
487                 }
488
489                 save = idl;
490                 idl = idl_intersection( op->o_bd, idl, tmp );
491                 idl_free( save );
492                 idl_free( tmp );
493
494                 if( idl == NULL ) break;
495         }
496
497         ber_bvarray_free_x( keys, op->o_tmpmemctx );
498
499         ldbm_cache_close( op->o_bd, db );
500
501
502 #ifdef NEW_LOGGING
503         LDAP_LOG( FILTER, ENTRY, 
504                    "equality_candidates: return %ld\n", 
505                    idl ? ID_BLOCK_NIDS(idl) : 0, 0, 0 );
506 #else
507         Debug( LDAP_DEBUG_TRACE, "<= equality_candidates %ld\n",
508             idl ? ID_BLOCK_NIDS(idl) : 0, 0, 0 );
509 #endif
510
511         return( idl );
512 }
513
514 static ID_BLOCK *
515 approx_candidates(
516     Operation *op,
517         AttributeAssertion *ava
518 )
519 {
520         ID_BLOCK *idl;
521         DBCache *db;
522         int i;
523         int rc;
524         char *dbname;
525         slap_mask_t mask;
526         struct berval prefix = {0, NULL};
527         struct berval *keys = NULL;
528         MatchingRule *mr;
529
530 #ifdef NEW_LOGGING
531         LDAP_LOG( FILTER, ENTRY, "approx_candidates: enter\n", 0, 0, 0 );
532 #else
533         Debug( LDAP_DEBUG_TRACE, "=> approx_candidates\n", 0, 0, 0 );
534 #endif
535
536
537         idl = idl_allids( op->o_bd );
538
539         rc = index_param( op->o_bd, ava->aa_desc, LDAP_FILTER_APPROX,
540                 &dbname, &mask, &prefix );
541
542         if( rc != LDAP_SUCCESS ) {
543 #ifdef NEW_LOGGING
544                 LDAP_LOG( FILTER, ERR, 
545                            "approx_candidates: index_param returned %d\n", rc, 0, 0 );
546 #else
547                 Debug( LDAP_DEBUG_TRACE,
548                     "<= approx_candidates: index_param returned=%d\n",
549                         rc, 0, 0 );
550 #endif
551
552                 return idl;
553         }
554
555         if( dbname == NULL ) {
556                 /* not indexed */
557 #ifdef NEW_LOGGING
558                 LDAP_LOG( FILTER, ERR, "approx_candidates: not indexed\n", 0, 0, 0 );
559 #else
560                 Debug( LDAP_DEBUG_ANY,
561                     "<= approx_candidates: not indexed\n",
562                         0, 0, 0 );
563 #endif
564
565                 return idl;
566         }
567
568         mr = ava->aa_desc->ad_type->sat_approx;
569         if( !mr ) {
570                 /* no approx matching rule, try equality matching rule */
571                 mr = ava->aa_desc->ad_type->sat_equality;
572         }
573
574         if( !mr ) {
575                 return idl;
576         }
577
578         if( !mr->smr_filter ) {
579                 return idl;
580         }
581
582         rc = (mr->smr_filter)(
583                 LDAP_FILTER_APPROX,
584                 mask,
585                 ava->aa_desc->ad_type->sat_syntax,
586                 mr,
587                 &prefix,
588                 &ava->aa_value,
589                 &keys, op->o_tmpmemctx );
590
591         if( rc != LDAP_SUCCESS ) {
592 #ifdef NEW_LOGGING
593                 LDAP_LOG( FILTER, ERR, 
594                            "approx_candidates: (%s%s) MR filter failed (%d)\n",
595                            dbname, LDBM_SUFFIX, rc );
596 #else
597                 Debug( LDAP_DEBUG_TRACE,
598                     "<= approx_candidates: (%s%s) MR filter failed (%d)\n",
599                         dbname, LDBM_SUFFIX, rc );
600 #endif
601
602                 return idl;
603         }
604
605         if( keys == NULL ) {
606 #ifdef NEW_LOGGING
607                 LDAP_LOG( FILTER, INFO, 
608                            "approx_candidates: no keys (%s%s)\n",
609                            dbname, LDBM_SUFFIX, 0 );
610 #else
611                 Debug( LDAP_DEBUG_TRACE,
612                     "<= approx_candidates: no keys (%s%s)\n",
613                         dbname, LDBM_SUFFIX, 0 );
614 #endif
615
616                 return idl;
617         }
618
619         db = ldbm_cache_open( op->o_bd, dbname, LDBM_SUFFIX, LDBM_WRCREAT );
620         
621         if ( db == NULL ) {
622 #ifdef NEW_LOGGING
623                 LDAP_LOG( FILTER, ERR, 
624                         "approx_candidates db open failed (%s%s)\n", 
625                         dbname, LDBM_SUFFIX, 0 );
626 #else
627                 Debug( LDAP_DEBUG_ANY,
628                     "<= approx_candidates db open failed (%s%s)\n",
629                         dbname, LDBM_SUFFIX, 0 );
630 #endif
631
632                 return idl;
633         }
634
635         for ( i= 0; keys[i].bv_val != NULL; i++ ) {
636                 ID_BLOCK *save;
637                 ID_BLOCK *tmp;
638
639                 rc = key_read( op->o_bd, db, &keys[i], &tmp );
640
641                 if( rc != LDAP_SUCCESS ) {
642                         idl_free( idl );
643                         idl = NULL;
644 #ifdef NEW_LOGGING
645                         LDAP_LOG( FILTER, ERR, 
646                                    "approx_candidates: key read failed (%d)\n", rc, 0, 0 );
647 #else
648                         Debug( LDAP_DEBUG_TRACE, "<= approx_candidates key read failed (%d)\n",
649                             rc, 0, 0 );
650 #endif
651
652                         break;
653                 }
654
655                 if( tmp == NULL ) {
656                         idl_free( idl );
657                         idl = NULL;
658 #ifdef NEW_LOGGING
659                         LDAP_LOG( FILTER, INFO, "approx_candidates: NULL\n", 0, 0, 0 );
660 #else
661                         Debug( LDAP_DEBUG_TRACE, "<= approx_candidates NULL\n",
662                             0, 0, 0 );
663 #endif
664
665                         break;
666                 }
667
668                 save = idl;
669                 idl = idl_intersection( op->o_bd, idl, tmp );
670                 idl_free( save );
671                 idl_free( tmp );
672
673                 if( idl == NULL ) break;
674         }
675
676         ber_bvarray_free_x( keys, op->o_tmpmemctx );
677
678         ldbm_cache_close( op->o_bd, db );
679
680 #ifdef NEW_LOGGING
681         LDAP_LOG( FILTER, ENTRY, 
682                 "approx_candidates: return %ld\n", 
683                 idl ? ID_BLOCK_NIDS(idl) : 0, 0, 0 );
684 #else
685         Debug( LDAP_DEBUG_TRACE, "<= approx_candidates %ld\n",
686             idl ? ID_BLOCK_NIDS(idl) : 0, 0, 0 );
687 #endif
688
689         return( idl );
690 }
691
692 static ID_BLOCK *
693 list_candidates(
694     Operation *op,
695     Filter      *flist,
696     int         ftype
697 )
698 {
699         ID_BLOCK        *idl, *tmp, *tmp2;
700         Filter  *f;
701
702 #ifdef NEW_LOGGING
703         LDAP_LOG( FILTER, ENTRY, "list_candidates: 0x%x\n", ftype, 0, 0 );
704 #else
705         Debug( LDAP_DEBUG_TRACE, "=> list_candidates 0x%x\n", ftype, 0, 0 );
706 #endif
707
708
709         idl = NULL;
710         for ( f = flist; f != NULL; f = f->f_next ) {
711                 if ( (tmp = filter_candidates( op, f )) == NULL &&
712                     ftype == LDAP_FILTER_AND ) {
713 #ifdef NEW_LOGGING
714                         LDAP_LOG( FILTER, INFO, "list_candidates: NULL\n", 0, 0, 0 );
715 #else
716                         Debug( LDAP_DEBUG_TRACE,
717                                "<= list_candidates NULL\n", 0, 0, 0 );
718 #endif
719
720                         idl_free( idl );
721                         return( NULL );
722                 }
723
724                 tmp2 = idl;
725                 if ( idl == NULL ) {
726                         idl = tmp;
727                 } else if ( ftype == LDAP_FILTER_AND ) {
728                         idl = idl_intersection( op->o_bd, idl, tmp );
729                         idl_free( tmp );
730                         idl_free( tmp2 );
731                 } else {
732                         idl = idl_union( op->o_bd, idl, tmp );
733                         idl_free( tmp );
734                         idl_free( tmp2 );
735                 }
736         }
737
738 #ifdef NEW_LOGGING
739         LDAP_LOG( FILTER, ENTRY, "list_candidates: return %ld\n",
740                    idl ? ID_BLOCK_NIDS(idl) : 0, 0, 0 );
741 #else
742         Debug( LDAP_DEBUG_TRACE, "<= list_candidates %ld\n",
743             idl ? ID_BLOCK_NIDS(idl) : 0, 0, 0 );
744 #endif
745
746         return( idl );
747 }
748
749 static ID_BLOCK *
750 substring_candidates(
751     Operation *op,
752     SubstringsAssertion *sub
753 )
754 {
755         ID_BLOCK *idl;
756         DBCache *db;
757         int i;
758         int rc;
759         char *dbname;
760         slap_mask_t mask;
761         struct berval prefix = {0, NULL};
762         struct berval *keys = NULL;
763         MatchingRule *mr;
764
765 #ifdef NEW_LOGGING
766         LDAP_LOG( FILTER, ENTRY, "substrings_candidates: enter\n", 0, 0, 0 );
767 #else
768         Debug( LDAP_DEBUG_TRACE, "=> substrings_candidates\n", 0, 0, 0 );
769 #endif
770
771
772         idl = idl_allids( op->o_bd );
773
774         rc = index_param( op->o_bd, sub->sa_desc, LDAP_FILTER_SUBSTRINGS,
775                 &dbname, &mask, &prefix );
776
777         if( rc != LDAP_SUCCESS ) {
778 #ifdef NEW_LOGGING
779                 LDAP_LOG( FILTER, ERR, 
780                            "substrings_candidates: index_param returned %d\n", rc, 0, 0 );
781 #else
782                 Debug( LDAP_DEBUG_TRACE,
783                     "<= substrings_candidates: index_param returned=%d\n",
784                         rc, 0, 0 );
785 #endif
786
787                 return idl;
788         }
789
790         if( dbname == NULL ) {
791                 /* not indexed */
792 #ifdef NEW_LOGGING
793                 LDAP_LOG( FILTER, ERR, "substrings_candidates: not indexed\n", 0, 0, 0);
794 #else
795                 Debug( LDAP_DEBUG_ANY,
796                     "<= substrings_candidates: not indexed\n",
797                         0, 0, 0 );
798 #endif
799
800                 return idl;
801         }
802
803         mr = sub->sa_desc->ad_type->sat_substr;
804
805         if( !mr ) {
806                 return idl;
807         }
808
809         if( !mr->smr_filter ) {
810                 return idl;
811         }
812
813         rc = (mr->smr_filter)(
814                 LDAP_FILTER_SUBSTRINGS,
815                 mask,
816                 sub->sa_desc->ad_type->sat_syntax,
817                 mr,
818                 &prefix,
819                 sub,
820                 &keys, op->o_tmpmemctx );
821
822         if( rc != LDAP_SUCCESS ) {
823 #ifdef NEW_LOGGING
824                 LDAP_LOG( FILTER, ERR, 
825                            "substrings_candidates: (%s%s) MR filter failed (%d)\n",
826                            dbname, LDBM_SUFFIX, rc );
827 #else
828                 Debug( LDAP_DEBUG_TRACE,
829                     "<= substrings_candidates: (%s%s) MR filter failed (%d)\n",
830                         dbname, LDBM_SUFFIX, rc );
831 #endif
832
833                 return idl;
834         }
835
836         if( keys == NULL ) {
837 #ifdef NEW_LOGGING
838                 LDAP_LOG( FILTER, ERR, 
839                            "substrings_candidates: (0x%04lx) no keys (%s%s)\n",
840                            mask, dbname, LDBM_SUFFIX );
841 #else
842                 Debug( LDAP_DEBUG_TRACE,
843                     "<= substrings_candidates: (0x%04lx) no keys (%s%s)\n",
844                         mask, dbname, LDBM_SUFFIX );
845 #endif
846
847                 return idl;
848         }
849
850         db = ldbm_cache_open( op->o_bd, dbname, LDBM_SUFFIX, LDBM_WRCREAT );
851         
852         if ( db == NULL ) {
853 #ifdef NEW_LOGGING
854                 LDAP_LOG( FILTER, ERR, 
855                            "substrings_candidates: db open failed (%s%s)\n",
856                            dbname, LDBM_SUFFIX, 0 );
857 #else
858                 Debug( LDAP_DEBUG_ANY,
859                     "<= substrings_candidates db open failed (%s%s)\n",
860                         dbname, LDBM_SUFFIX, 0 );
861 #endif
862
863                 return idl;
864         }
865
866         for ( i= 0; keys[i].bv_val != NULL; i++ ) {
867                 ID_BLOCK *save;
868                 ID_BLOCK *tmp;
869
870                 rc = key_read( op->o_bd, db, &keys[i], &tmp );
871
872                 if( rc != LDAP_SUCCESS ) {
873                         idl_free( idl );
874                         idl = NULL;
875 #ifdef NEW_LOGGING
876                         LDAP_LOG( FILTER, ERR, 
877                                    "substrings_candidates: key read failed (%d)\n", rc, 0, 0 );
878 #else
879                         Debug( LDAP_DEBUG_TRACE, "<= substrings_candidates key read failed (%d)\n",
880                             rc, 0, 0 );
881 #endif
882
883                         break;
884                 }
885
886                 if( tmp == NULL ) {
887                         idl_free( idl );
888                         idl = NULL;
889 #ifdef NEW_LOGGING
890                         LDAP_LOG( FILTER, INFO, "substrings_candidates: NULL\n", 0, 0, 0 );
891 #else
892                         Debug( LDAP_DEBUG_TRACE, "<= substrings_candidates NULL\n",
893                             0, 0, 0 );
894 #endif
895
896                         break;
897                 }
898
899                 save = idl;
900                 idl = idl_intersection( op->o_bd, idl, tmp );
901                 idl_free( save );
902                 idl_free( tmp );
903
904                 if( idl == NULL ) break;
905         }
906
907         ber_bvarray_free_x( keys, op->o_tmpmemctx );
908
909         ldbm_cache_close( op->o_bd, db );
910
911 #ifdef NEW_LOGGING
912         LDAP_LOG( FILTER, ENTRY, 
913                    "substrings_candidates: return %ld\n",
914                    idl ? ID_BLOCK_NIDS(idl) : 0, 0, 0 );
915 #else
916         Debug( LDAP_DEBUG_TRACE, "<= substrings_candidates %ld\n",
917             idl ? ID_BLOCK_NIDS(idl) : 0, 0, 0 );
918 #endif
919
920         return( idl );
921 }