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