]> git.sur5r.net Git - openldap/blobdiff - servers/slapd/overlays/pcache.c
Fix typo in prev commit
[openldap] / servers / slapd / overlays / pcache.c
index 26fcf98e87b6b0085ca1fe52a3dddb469b30ec44..710df5d789c2e4891f6172cc7a08122bce279516 100644 (file)
@@ -75,6 +75,8 @@ typedef struct cached_query_s {
        int                                             q_sizelimit;
        struct query_template_s         *qtemp; /* template of the query */
        time_t                                          expiry_time;    /* time till the query is considered valid */
+       unsigned long                   answerable_cnt; /* how many times it was answerable */
+       ldap_pvt_thread_mutex_t         answerable_cnt_mutex;
        struct cached_query_s           *next;          /* next query in the template */
        struct cached_query_s           *prev;          /* previous query in the template */
        struct cached_query_s           *lru_up;        /* previous query in the LRU list */
@@ -130,6 +132,7 @@ typedef struct query_template_s {
        time_t          ttl;            /* TTL for the queries of this template */
        time_t          negttl;         /* TTL for negative results */
        time_t          limitttl;       /* TTL for sizelimit exceeding results */
+       time_t          ttr;    /* time to refresh */
        struct attr_set t_attrs;        /* filter attrs + attr_set */
 } QueryTemplate;
 
@@ -263,15 +266,21 @@ remove_query_data(
  * Turn a cached query into its URL representation
  */
 static int
-query2url( Operation *op, CachedQuery *q, struct berval *urlbv )
+query2url( Operation *op, CachedQuery *q, struct berval *urlbv, int dolock )
 {
        struct berval   bv_scope,
                        bv_filter;
        char            attrset_buf[ LDAP_PVT_INTTYPE_CHARS( unsigned long ) ],
                        expiry_buf[ LDAP_PVT_INTTYPE_CHARS( unsigned long ) ],
+                       answerable_buf[ LDAP_PVT_INTTYPE_CHARS( unsigned long ) ],
                        *ptr;
        ber_len_t       attrset_len,
-                       expiry_len;
+                       expiry_len,
+                       answerable_len;
+
+       if ( dolock ) {
+               ldap_pvt_thread_rdwr_rlock( &q->rwlock );
+       }
 
        ldap_pvt_scope2bv( q->scope, &bv_scope );
        filter2bv_x( op, q->filter, &bv_filter );
@@ -279,6 +288,8 @@ query2url( Operation *op, CachedQuery *q, struct berval *urlbv )
                "%lu", (unsigned long)q->qtemp->attr_set_index );
        expiry_len = sprintf( expiry_buf,
                "%lu", (unsigned long)q->expiry_time );
+       answerable_len = snprintf( answerable_buf, sizeof( answerable_buf ),
+               "%lu", q->answerable_cnt );
 
        urlbv->bv_len = STRLENOF( "ldap:///" )
                + q->qbase->base.bv_len
@@ -291,7 +302,9 @@ query2url( Operation *op, CachedQuery *q, struct berval *urlbv )
                + STRLENOF( ",x-attrset=" )
                + attrset_len
                + STRLENOF( ",x-expiry=" )
-               + expiry_len;
+               + expiry_len
+               + STRLENOF( ",x-answerable=" )
+               + answerable_len;
        ptr = urlbv->bv_val = ber_memalloc_x( urlbv->bv_len + 1, op->o_tmpmemctx );
        ptr = lutil_strcopy( ptr, "ldap:///" );
        ptr = lutil_strcopy( ptr, q->qbase->base.bv_val );
@@ -305,9 +318,15 @@ query2url( Operation *op, CachedQuery *q, struct berval *urlbv )
        ptr = lutil_strcopy( ptr, attrset_buf );
        ptr = lutil_strcopy( ptr, ",x-expiry=" );
        ptr = lutil_strcopy( ptr, expiry_buf );
+       ptr = lutil_strcopy( ptr, ",x-answerable=" );
+       ptr = lutil_strcopy( ptr, answerable_buf );
 
        ber_memfree_x( bv_filter.bv_val, op->o_tmpmemctx );
 
+       if ( dolock ) {
+               ldap_pvt_thread_rdwr_runlock( &q->rwlock );
+       }
+
        return 0;
 }
 
@@ -330,10 +349,14 @@ url2query(
                        uuid;
        int             attrset;
        time_t          expiry_time;
+       unsigned long   answerable_cnt;
        int             i,
-                       got_uuid = 0,
-                       got_attrset = 0,
-                       got_expiry = 0,
+                       got = 0,
+#define GOT_UUID       0x1U
+#define GOT_ATTRSET    0x2U
+#define GOT_EXPIRY     0x4U
+#define GOT_ANSWERABLE 0x8U
+#define GOT_ALL                (GOT_UUID|GOT_ATTRSET|GOT_EXPIRY|GOT_ANSWERABLE)
                        rc = 0;
 
        rc = ldap_url_parse( url, &lud );
@@ -391,29 +414,56 @@ url2query(
                        struct berval   tmpUUID;
                        Syntax          *syn_UUID = slap_schema.si_ad_entryUUID->ad_type->sat_syntax;
 
+                       if ( got & GOT_UUID ) {
+                               rc = 1;
+                               goto error;
+                       }
+
                        ber_str2bv( &lud->lud_exts[ i ][ STRLENOF( "x-uuid=" ) ], 0, 0, &tmpUUID );
                        rc = syn_UUID->ssyn_pretty( syn_UUID, &tmpUUID, &uuid, NULL );
                        if ( rc != LDAP_SUCCESS ) {
                                goto error;
                        }
-                       got_uuid = 1;
+                       got |= GOT_UUID;
 
                } else if ( strncmp( lud->lud_exts[ i ], "x-attrset=", STRLENOF( "x-attrset=" ) ) == 0 ) {
+                       if ( got & GOT_ATTRSET ) {
+                               rc = 1;
+                               goto error;
+                       }
+
                        rc = lutil_atoi( &attrset, &lud->lud_exts[ i ][ STRLENOF( "x-attrset=" ) ] );
                        if ( rc ) {
                                goto error;
                        }
-                       got_attrset = 1;
+                       got |= GOT_ATTRSET;
 
                } else if ( strncmp( lud->lud_exts[ i ], "x-expiry=", STRLENOF( "x-expiry=" ) ) == 0 ) {
                        unsigned long l;
 
+                       if ( got & GOT_EXPIRY ) {
+                               rc = 1;
+                               goto error;
+                       }
+
                        rc = lutil_atoul( &l, &lud->lud_exts[ i ][ STRLENOF( "x-expiry=" ) ] );
                        if ( rc ) {
                                goto error;
                        }
                        expiry_time = (time_t)l;
-                       got_expiry = 1;
+                       got |= GOT_EXPIRY;
+
+               } else if ( strncmp( lud->lud_exts[ i ], "x-answerable=", STRLENOF( "x-answerable=" ) ) == 0 ) {
+                       if ( got & GOT_ANSWERABLE ) {
+                               rc = 1;
+                               goto error;
+                       }
+
+                       rc = lutil_atoul( &answerable_cnt, &lud->lud_exts[ i ][ STRLENOF( "x-answerable=" ) ] );
+                       if ( rc ) {
+                               goto error;
+                       }
+                       got |= GOT_ANSWERABLE;
 
                } else {
                        rc = -1;
@@ -421,17 +471,7 @@ url2query(
                }
        }
 
-       if ( !got_uuid ) {
-               rc = 1;
-               goto error;
-       }
-
-       if ( !got_attrset ) {
-               rc = 1;
-               goto error;
-       }
-
-       if ( !got_expiry ) {
+       if ( got != GOT_ALL ) {
                rc = 1;
                goto error;
        }
@@ -482,6 +522,7 @@ url2query(
                if ( cq != NULL ) {
                        cq->expiry_time = expiry_time;
                        cq->q_uuid = uuid;
+                       cq->answerable_cnt = answerable_cnt;
 
                        /* it's now into cq->filter */
                        BER_BVZERO( &uuid );
@@ -1177,6 +1218,7 @@ free_query (CachedQuery* qc)
 {
        free(qc->q_uuid.bv_val);
        filter_free(qc->filter);
+       ldap_pvt_thread_mutex_destroy(&qc->answerable_cnt_mutex);
        ldap_pvt_thread_rdwr_destroy( &qc->rwlock );
        memset(qc, 0, sizeof(*qc));
        free(qc);
@@ -1221,6 +1263,10 @@ add_query(
                break;
        }
        new_cached_query->expiry_time = slap_get_time() + ttl;
+
+       new_cached_query->answerable_cnt = 0;
+       ldap_pvt_thread_mutex_init(&new_cached_query->answerable_cnt_mutex);
+
        new_cached_query->lru_up = NULL;
        new_cached_query->lru_down = NULL;
        Debug( pcache_debug, "Added query expires at %ld (%s)\n",
@@ -2041,7 +2087,8 @@ over:;
                        op->ors_attrs = si->save_attrs;
                }
                if ( (op->o_abandon || rs->sr_err == SLAPD_ABANDON) && 
-                               si->caching_reason == PC_IGNORE ) {
+                               si->caching_reason == PC_IGNORE )
+               {
                        filter_free( si->query.filter );
                        if ( si->count ) {
                                /* duplicate query, free it */
@@ -2363,7 +2410,8 @@ pcache_op_search(
        tempstr.bv_val = op->o_tmpalloc( op->ors_filterstr.bv_len+1, op->o_tmpmemctx );
        tempstr.bv_len = 0;
        if ( filter2template( op, op->ors_filter, &tempstr, &filter_attrs,
-               &fattr_cnt, &fattr_got_oc )) {
+               &fattr_cnt, &fattr_got_oc ))
+       {
                op->o_tmpfree( tempstr.bv_val, op->o_tmpmemctx );
                return SLAP_CB_CONTINUE;
        }
@@ -2385,15 +2433,15 @@ pcache_op_search(
                QueryTemplate *qt = qm->attr_sets[attr_set].templates;
                for (; qt; qt = qt->qtnext ) {
                        /* find if template i can potentially answer tempstr */
-                       if (qt->querystr.bv_len != tempstr.bv_len ||
-                               strcasecmp( qt->querystr.bv_val, tempstr.bv_val ))
+                       if ( ber_bvstrcasecmp( &qt->querystr, &tempstr ) != 0 )
                                continue;
                        cacheable = 1;
                        qtemp = qt;
                        Debug( pcache_debug, "Entering QC, querystr = %s\n",
                                        op->ors_filterstr.bv_val, 0, 0 );
-                       answerable = (*(qm->qcfunc))(op, qm, &query, qt);
+                       answerable = qm->qcfunc(op, qm, &query, qt);
 
+                       /* if != NULL, rlocks qtemp->t_rwlock */
                        if (answerable)
                                break;
                }
@@ -2404,7 +2452,12 @@ pcache_op_search(
                BackendDB       *save_bd = op->o_bd;
                slap_callback   *save_cb = op->o_callback;
 
-               Debug( pcache_debug, "QUERY ANSWERABLE\n", 0, 0, 0 );
+               ldap_pvt_thread_mutex_lock( &answerable->answerable_cnt_mutex );
+               answerable->answerable_cnt++;
+               Debug( pcache_debug, "QUERY ANSWERABLE (answered %lu times)\n",
+                       answerable->answerable_cnt, 0, 0 );
+               ldap_pvt_thread_mutex_unlock( &answerable->answerable_cnt_mutex );
+
                op->o_tmpfree( filter_attrs, op->o_tmpmemctx );
                ldap_pvt_thread_rdwr_rlock(&answerable->rwlock);
                if ( BER_BVISNULL( &answerable->q_uuid )) {
@@ -2422,6 +2475,7 @@ pcache_op_search(
                        i = cm->db.bd_info->bi_op_search( op, rs );
                }
                ldap_pvt_thread_rdwr_runlock(&answerable->rwlock);
+               /* locked by qtemp->qcfunc (query_containment) */
                ldap_pvt_thread_rdwr_runlock(&qtemp->t_rwlock);
                op->o_bd = save_bd;
                op->o_callback = save_cb;
@@ -2522,7 +2576,7 @@ get_attr_set(
                count = 1;
                attrs = slap_anlist_all_user_attributes;
 
-       } else if ( count == 1 && strcmp( attrs[0].an_name.bv_val, LDAP_NO_ATTRS ) == 0 ) {
+       } else if ( count == 1 && bvmatch( &attrs[0].an_name, slap_bv_no_attrs ) ) {
                count = 0;
                attrs = NULL;
        }
@@ -2663,7 +2717,8 @@ enum {
        PC_TEMP,
        PC_RESP,
        PC_QUERIES,
-       PC_OFFLINE
+       PC_OFFLINE,
+       PC_PRIVATE_DB
 };
 
 static ConfigDriver pc_cf_gen;
@@ -2671,48 +2726,77 @@ static ConfigLDAPadd pc_ldadd;
 static ConfigCfAdd pc_cfadd;
 
 static ConfigTable pccfg[] = {
-       { "proxycache", "backend> <max_entries> <numattrsets> <entry limit> "
+       { "pcache", "backend> <max_entries> <numattrsets> <entry limit> "
                                "<cycle_time",
                6, 6, 0, ARG_MAGIC|ARG_NO_DELETE|PC_MAIN, pc_cf_gen,
-               "( OLcfgOvAt:2.1 NAME 'olcProxyCache' "
-                       "DESC 'ProxyCache basic parameters' "
+               "( OLcfgOvAt:2.1 NAME ( 'olcPcache' 'olcProxyCache' ) "
+                       "DESC 'Proxy Cache basic parameters' "
                        "SYNTAX OMsDirectoryString SINGLE-VALUE )", NULL, NULL },
-       { "proxyattrset", "index> <attributes...",
+       { "pcacheAttrset", "index> <attributes...",
                2, 0, 0, ARG_MAGIC|PC_ATTR, pc_cf_gen,
-               "( OLcfgOvAt:2.2 NAME 'olcProxyAttrset' "
+               "( OLcfgOvAt:2.2 NAME ( 'olcPcacheAttrset' 'olcProxyAttrset' ) "
                        "DESC 'A set of attributes to cache' "
                        "SYNTAX OMsDirectoryString )", NULL, NULL },
-       { "proxytemplate", "filter> <attrset-index> <TTL> <negTTL",
-               4, 6, 0, ARG_MAGIC|PC_TEMP, pc_cf_gen,
-               "( OLcfgOvAt:2.3 NAME 'olcProxyTemplate' "
+       { "pcacheTemplate", "filter> <attrset-index> <TTL> <negTTL> "
+                       "<limitTTL> <TTR",
+               4, 7, 0, ARG_MAGIC|PC_TEMP, pc_cf_gen,
+               "( OLcfgOvAt:2.3 NAME ( 'olcPcacheTemplate' 'olcProxyCacheTemplate' ) "
                        "DESC 'Filter template, attrset, cache TTL, "
-                               "optional negative TTL, optional sizelimit TTL' "
+                               "optional negative TTL, optional sizelimit TTL, "
+                               "optional TTR' "
                        "SYNTAX OMsDirectoryString )", NULL, NULL },
-       { "response-callback", "head|tail(default)",
+       { "pcachePosition", "head|tail(default)",
                2, 2, 0, ARG_MAGIC|PC_RESP, pc_cf_gen,
-               "( OLcfgOvAt:2.4 NAME 'olcProxyResponseCB' "
+               "( OLcfgOvAt:2.4 NAME 'olcPcachePosition' "
                        "DESC 'Response callback position in overlay stack' "
                        "SYNTAX OMsDirectoryString )", NULL, NULL },
-       { "proxyCacheQueries", "queries",
+       { "pcacheMaxQueries", "queries",
                2, 2, 0, ARG_INT|ARG_MAGIC|PC_QUERIES, pc_cf_gen,
-               "( OLcfgOvAt:2.5 NAME 'olcProxyCacheQueries' "
+               "( OLcfgOvAt:2.5 NAME ( 'olcPcacheMaxQueries' 'olcProxyCacheQueries' ) "
                        "DESC 'Maximum number of queries to cache' "
                        "SYNTAX OMsInteger )", NULL, NULL },
-       { "proxySaveQueries", "TRUE|FALSE",
+       { "pcachePersist", "TRUE|FALSE",
                2, 2, 0, ARG_ON_OFF|ARG_OFFSET, (void *)offsetof(cache_manager, save_queries),
-               "( OLcfgOvAt:2.6 NAME 'olcProxySaveQueries' "
+               "( OLcfgOvAt:2.6 NAME ( 'olcPcachePersist' 'olcProxySaveQueries' ) "
                        "DESC 'Save cached queries for hot restart' "
                        "SYNTAX OMsBoolean )", NULL, NULL },
-       { "proxyCheckCacheability", "TRUE|FALSE",
+       { "pcacheValidate", "TRUE|FALSE",
                2, 2, 0, ARG_ON_OFF|ARG_OFFSET, (void *)offsetof(cache_manager, check_cacheability),
-               "( OLcfgOvAt:2.7 NAME 'olcProxyCheckCacheability' "
+               "( OLcfgOvAt:2.7 NAME ( 'olcPcacheValidate' 'olcProxyCheckCacheability' ) "
                        "DESC 'Check whether the results of a query are cacheable, e.g. for schema issues' "
                        "SYNTAX OMsBoolean )", NULL, NULL },
-       { "proxyCacheOffline", "TRUE|FALSE",
+       { "pcacheOffline", "TRUE|FALSE",
                2, 2, 0, ARG_ON_OFF|ARG_MAGIC|PC_OFFLINE, pc_cf_gen,
-               "( OLcfgOvAt:2.8 NAME 'olcProxyCacheOffline' "
+               "( OLcfgOvAt:2.8 NAME 'olcPcacheOffline' "
                        "DESC 'Set cache to offline mode and disable expiration' "
                        "SYNTAX OMsBoolean )", NULL, NULL },
+       { "pcache-", "private database args",
+               1, 0, STRLENOF("pcache-"), ARG_MAGIC|PC_PRIVATE_DB, pc_cf_gen,
+               NULL, NULL, NULL },
+
+       /* Legacy keywords */
+       { "proxycache", "backend> <max_entries> <numattrsets> <entry limit> "
+                               "<cycle_time",
+               6, 6, 0, ARG_MAGIC|ARG_NO_DELETE|PC_MAIN, pc_cf_gen,
+               NULL, NULL, NULL },
+       { "proxyattrset", "index> <attributes...",
+               2, 0, 0, ARG_MAGIC|PC_ATTR, pc_cf_gen,
+               NULL, NULL, NULL },
+       { "proxytemplate", "filter> <attrset-index> <TTL> <negTTL",
+               4, 6, 0, ARG_MAGIC|PC_TEMP, pc_cf_gen,
+               NULL, NULL, NULL },
+       { "response-callback", "head|tail(default)",
+               2, 2, 0, ARG_MAGIC|PC_RESP, pc_cf_gen,
+               NULL, NULL, NULL },
+       { "proxyCacheQueries", "queries",
+               2, 2, 0, ARG_INT|ARG_MAGIC|PC_QUERIES, pc_cf_gen,
+               NULL, NULL, NULL },
+       { "proxySaveQueries", "TRUE|FALSE",
+               2, 2, 0, ARG_ON_OFF|ARG_OFFSET, (void *)offsetof(cache_manager, save_queries),
+               NULL, NULL, NULL },
+       { "proxyCheckCacheability", "TRUE|FALSE",
+               2, 2, 0, ARG_ON_OFF|ARG_OFFSET, (void *)offsetof(cache_manager, check_cacheability),
+               NULL, NULL, NULL },
 
        { NULL, NULL, 0, 0, 0, ARG_IGNORED }
 };
@@ -2722,8 +2806,9 @@ static ConfigOCs pcocs[] = {
                "NAME 'olcPcacheConfig' "
                "DESC 'ProxyCache configuration' "
                "SUP olcOverlayConfig "
-               "MUST ( olcProxyCache $ olcProxyAttrset $ olcProxyTemplate ) "
-               "MAY ( olcProxyResponseCB $ olcProxyCacheQueries $ olcProxySaveQueries $ olcProxyCheckCacheability $ olcProxyCacheOffline ) )",
+               "MUST ( olcPcache $ olcPcacheAttrset $ olcPcacheTemplate ) "
+               "MAY ( olcPcachePosition $ olcPcacheMaxQueries $ olcPcachePersist $ "
+                       "olcPcacheValidate $ olcPcacheOffline ) )",
                Cft_Overlay, pccfg, NULL, pc_cfadd },
        { "( OLcfgOvOc:2.2 "
                "NAME 'olcPcacheDatabase' "
@@ -2843,11 +2928,12 @@ pc_cf_gen( ConfigArgs *c )
                                /* HEADS-UP: always print all;
                                 * if optional == 0, ignore */
                                bv.bv_len = snprintf( c->cr_msg, sizeof( c->cr_msg ),
-                                       " %d %ld %ld %ld",
+                                       " %d %ld %ld %ld %ld",
                                        temp->attr_set_index,
                                        temp->ttl,
                                        temp->negttl,
-                                       temp->limitttl );
+                                       temp->limitttl,
+                                       temp->ttr );
                                bv.bv_len += temp->querystr.bv_len + 2;
                                bv.bv_val = ch_malloc( bv.bv_len+1 );
                                ptr = bv.bv_val;
@@ -3112,7 +3198,19 @@ pc_cf_gen( ConfigArgs *c )
                temp->ttl = (time_t)t;
                temp->negttl = (time_t)0;
                temp->limitttl = (time_t)0;
+               temp->ttr = (time_t)0;
                switch ( c->argc ) {
+               case 7:
+                       if ( lutil_parse_time( c->argv[6], &t ) != 0 ) {
+                               snprintf( c->cr_msg, sizeof( c->cr_msg ),
+                                       "unable to parse template ttr=\"%s\"",
+                                       c->argv[6] );
+                               Debug( LDAP_DEBUG_CONFIG, "%s: %s.\n", c->log, c->cr_msg, 0 );
+                                       return( 1 );
+                       }
+                       temp->ttr = (time_t)t;
+                       /* fallthru */
+
                case 6:
                        if ( lutil_parse_time( c->argv[5], &t ) != 0 ) {
                                snprintf( c->cr_msg, sizeof( c->cr_msg ),
@@ -3180,7 +3278,62 @@ pc_cf_gen( ConfigArgs *c )
                else
                        cm->cc_paused &= ~PCACHE_CC_OFFLINE;
                break;
+       case PC_PRIVATE_DB:
+               if ( cm->db.be_private == NULL ) {
+                       snprintf( c->cr_msg, sizeof( c->cr_msg ),
+                               "private database must be defined before setting database specific options" );
+                       Debug( LDAP_DEBUG_CONFIG, "%s: %s.\n", c->log, c->cr_msg, 0 );
+                       return( 1 );
+               }
+
+               if ( cm->db.bd_info->bi_cf_ocs ) {
+                       ConfigTable     *ct;
+                       ConfigArgs      c2 = *c;
+                       char            *argv0 = c->argv[ 0 ];
+
+                       c->argv[ 0 ] = &argv0[ STRLENOF( "proxycache-" ) ];
+
+                       ct = config_find_keyword( cm->db.bd_info->bi_cf_ocs->co_table, c );
+                       if ( ct == NULL ) {
+                               snprintf( c->cr_msg, sizeof( c->cr_msg ),
+                                       "private database does not recognize specific option '%s'",
+                                       c->argv[ 0 ] );
+                               Debug( LDAP_DEBUG_CONFIG, "%s: %s.\n", c->log, c->cr_msg, 0 );
+                               rc = 1;
+
+                       } else {
+                               c->table = cm->db.bd_info->bi_cf_ocs->co_type;
+                               c->be = &cm->db;
+                               c->bi = c->be->bd_info;
+
+                               rc = config_add_vals( ct, c );
+
+                               c->bi = c2.bi;
+                               c->be = c2.be;
+                               c->table = c2.table;
+                       }
+
+                       c->argv[ 0 ] = argv0;
+
+               } else if ( cm->db.be_config != NULL ) {
+                       char    *argv0 = c->argv[ 0 ];
+
+                       c->argv[ 0 ] = &argv0[ STRLENOF( "proxycache-" ) ];
+                       rc = cm->db.be_config( &cm->db, c->fname, c->lineno, c->argc, c->argv );
+                       c->argv[ 0 ] = argv0;
+
+               } else {
+                       snprintf( c->cr_msg, sizeof( c->cr_msg ),
+                               "no means to set private database specific options" );
+                       Debug( LDAP_DEBUG_CONFIG, "%s: %s.\n", c->log, c->cr_msg, 0 );
+                       return 1;
+               }
+               break;
+       default:
+               rc = SLAP_CONF_UNKNOWN;
+               break;
        }
+
        return rc;
 }
 
@@ -3511,7 +3664,7 @@ pcache_db_close(
                                for ( qc = tm->query; qc; qc = qc->next ) {
                                        struct berval   bv;
 
-                                       if ( query2url( op, qc, &bv ) == 0 ) {
+                                       if ( query2url( op, qc, &bv, 0 ) == 0 ) {
                                                ber_bvarray_add_x( &vals, &bv, op->o_tmpmemctx );
                                        }
                                }