Filter *flist,
int ftype,
ID *ids,
- ID *tmp );
+ ID *tmp,
+ ID *stack );
int
bdb_filter_candidates(
Backend *be,
Filter *f,
ID *ids,
- ID *tmp )
+ ID *tmp,
+ ID *stack )
{
int rc = -1;
#ifdef NEW_LOGGING
Debug( LDAP_DEBUG_FILTER, "\tAND\n", 0, 0, 0 );
#endif
rc = list_candidates( be,
- f->f_and, LDAP_FILTER_AND, ids, tmp );
+ f->f_and, LDAP_FILTER_AND, ids, tmp, stack );
break;
case LDAP_FILTER_OR:
Debug( LDAP_DEBUG_FILTER, "\tOR\n", 0, 0, 0 );
#endif
rc = list_candidates( be,
- f->f_or, LDAP_FILTER_OR, ids, tmp );
+ f->f_or, LDAP_FILTER_OR, ids, tmp, stack );
break;
default:
Filter *flist,
int ftype,
ID *ids,
- ID *tmp )
+ ID *tmp,
+ ID *save )
{
struct bdb_info *bdb = (struct bdb_info *) be->be_private;
int rc = 0;
Filter *f;
-/* Systems that can't increase thread stack size will die with these
- * structures allocated on the stack. */
-#if !defined(LDAP_PVT_THREAD_STACK_SIZE) || (LDAP_PVT_THREAD_STACK_SIZE == 0)
- ID *save = ch_malloc(BDB_IDL_UM_SIZEOF);
-#else
- ID save[BDB_IDL_UM_SIZE];
-#endif
-
#ifdef NEW_LOGGING
LDAP_LOG (( "filterindex", LDAP_LEVEL_ARGS, "=> bdb_list_candidates: 0x%x\n", ftype));
#else
}
for ( f = flist; f != NULL; f = f->f_next ) {
- rc = bdb_filter_candidates( be, f, save, tmp );
+ rc = bdb_filter_candidates( be, f, save, tmp,
+ save+BDB_IDL_UM_SIZE );
if ( rc != 0 ) {
if ( ftype == LDAP_FILTER_AND ) {
}
}
-#if !defined(LDAP_PVT_THREAD_STACK_SIZE) || (LDAP_PVT_THREAD_STACK_SIZE == 0)
- free(save);
-#endif
-
if( rc ) {
#ifdef NEW_LOGGING
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 ) ));
}
/* Is "objectClass=xx" mentioned anywhere in this filter? Presence
- * doesn't count, we're looking for explicit values.
+ * doesn't count, we're looking for explicit values. Also count depth
+ * of filter tree while we're at it.
*/
static int oc_filter(
- Filter *f
+ Filter *f,
+ int cur,
+ int *max
)
{
int rc = 0;
+ if( cur > *max ) *max = cur;
+
switch(f->f_choice) {
case LDAP_FILTER_EQUALITY:
case LDAP_FILTER_APPROX:
case LDAP_FILTER_AND:
case LDAP_FILTER_OR:
+ cur++;
for (f=f->f_and; f; f=f->f_next)
- if ((rc = oc_filter(f)))
+ if ((rc = oc_filter(f, cur, max)))
break;
break;
default:
int deref,
ID *ids )
{
- int rc;
+ int rc, depth = 1;
Filter f, scopef, rf, xf;
- ID tmp[BDB_IDL_UM_SIZE];
+ ID *stack;
AttributeAssertion aa_ref;
#ifdef BDB_SUBENTRIES
Filter sf;
/* If the user's filter doesn't mention objectClass, or if
* it just uses objectClass=*, these clauses are redundant.
*/
- if (oc_filter(filter) && !get_subentries_visibility(op) ) {
+ if (oc_filter(filter, 1, &depth) && !get_subentries_visibility(op) ) {
if( !get_manageDSAit(op) ) { /* match referrals */
struct berval bv_ref = { sizeof("REFERRAL")-1, "REFERRAL" };
rf.f_choice = LDAP_FILTER_EQUALITY;
xf.f_or = ⁡
}
#endif
+ /* We added one of these clauses, filter depth increased */
+ if( xf.f_or != filter ) depth++;
}
f.f_next = NULL;
: SLAPD_FILTER_DN_ONE;
scopef.f_dn = &e->e_nname;
scopef.f_next = xf.f_or == filter ? filter : &xf ;
+ /* Filter depth increased again, adding scope clause */
+ depth++;
#ifdef BDB_SUBENTRIES
if( get_subentries_visibility( op ) ) {
}
#endif
- rc = bdb_filter_candidates( be, &f, ids, tmp );
+ /* Allocate IDL stack, plus 1 more for former tmp */
+ stack = malloc( (depth + 1) * BDB_IDL_UM_SIZE * sizeof( ID ) );
+
+ rc = bdb_filter_candidates( be, &f, ids, stack, stack+BDB_IDL_UM_SIZE );
+
+ free( stack );
if( rc ) {
#ifdef NEW_LOGGING