From c754bc430c2d637aefadad43255a63dc92aae2b5 Mon Sep 17 00:00:00 2001 From: Noriko Hosoi Date: Thu, 26 Feb 2015 17:39:36 -0800 Subject: [PATCH 1/2] Ticket #48109 - substring index with nssubstrbegin: 1 is not being used with filters like (attr=x*) Description: subString index width was not properly passed to the syntax plugin in the substr search. This patch fixes a couple of issues. 1. Pass substrlen array to syntax plugin by stashing it in pblock with SLAPI_SYNTAX_SUBSTRLENS. 2. Advertised format "nsSubStr{Begin,Middle,End}: width" was not supported. It is again supported. 3. If both "nsSubStr{Begin,Middle,End}: width" and "nsMatchingRule: nsSubStr{Begin,Middle,End}=width" are specified, the former is honored, the latter is used if the former directive does not exist. --- ldap/servers/slapd/back-ldbm/filterindex.c | 5 ++- ldap/servers/slapd/back-ldbm/ldbm_attr.c | 70 ++++++++++++++++++++++++------ ldap/servers/slapd/plugin_syntax.c | 22 ++++++++-- ldap/servers/slapd/slapi-plugin.h | 2 + 4 files changed, 81 insertions(+), 18 deletions(-) diff --git a/ldap/servers/slapd/back-ldbm/filterindex.c b/ldap/servers/slapd/back-ldbm/filterindex.c index c8c40c4..3246192 100644 --- a/ldap/servers/slapd/back-ldbm/filterindex.c +++ b/ldap/servers/slapd/back-ldbm/filterindex.c @@ -936,6 +936,7 @@ substring_candidates( Slapi_Attr sattr; back_txn txn = {NULL}; int pr_idx = -1; + struct attrinfo *ai = NULL; LDAPDebug( LDAP_DEBUG_TRACE, "=> sub_candidates\n", 0, 0, 0 ); @@ -950,7 +951,9 @@ substring_candidates( * assertion values */ slapi_attr_init(&sattr, type); - slapi_attr_assertion2keys_sub_sv( &sattr, initial, any, final, &ivals ); + ainfo_get(be, type, &ai); + slapi_pblock_set(pb, SLAPI_SYNTAX_SUBSTRLENS, ai->ai_substr_lens ); + slapi_attr_assertion2keys_sub_sv_pb( pb, &sattr, initial, any, final, &ivals ); attr_done(&sattr); slapi_pblock_get(pb, SLAPI_PAGED_RESULTS_INDEX, &pr_idx); if ( ivals == NULL || *ivals == NULL ) { diff --git a/ldap/servers/slapd/back-ldbm/ldbm_attr.c b/ldap/servers/slapd/back-ldbm/ldbm_attr.c index 7b3f664..61f1b46 100644 --- a/ldap/servers/slapd/back-ldbm/ldbm_attr.c +++ b/ldap/servers/slapd/back-ldbm/ldbm_attr.c @@ -677,6 +677,7 @@ attr_index_config( Slapi_Attr *attr; int mr_count = 0; char myreturntext[SLAPI_DSE_RETURNTEXT_SIZE]; + int substrval = 0; /* Get the cn */ if (0 == slapi_entry_attr_find(e, "cn", &attr)) { @@ -762,6 +763,31 @@ attr_index_config( * ordering matching rule compatible with the attribute syntax, and there is * a compare function. If not, we assume it is a RULE index definition. */ + /* + * nsSubStrBegin: 2 + * nsSubStrMiddle: 2 + * nsSubStrEnd: 2 + */ + substrval = slapi_entry_attr_get_int(e, INDEX_ATTR_SUBSTRBEGIN); + if (substrval) { + substrlens = (int *)slapi_ch_calloc(1, sizeof(int) * INDEX_SUBSTRLEN); + substrlens[INDEX_SUBSTRBEGIN] = substrval; + } + substrval = slapi_entry_attr_get_int(e, INDEX_ATTR_SUBSTRMIDDLE); + if (substrval) { + if (!substrlens) { + substrlens = (int *)slapi_ch_calloc(1, sizeof(int) * INDEX_SUBSTRLEN); + } + substrlens[INDEX_SUBSTRMIDDLE] = substrval; + } + substrval = slapi_entry_attr_get_int(e, INDEX_ATTR_SUBSTREND); + if (substrval) { + if (!substrlens) { + substrlens = (int *)slapi_ch_calloc(1, sizeof(int) * INDEX_SUBSTRLEN); + } + substrlens[INDEX_SUBSTREND] = substrval; + } + a->ai_substr_lens = substrlens; if(0 == slapi_entry_attr_find(e, "nsMatchingRule", &attr)){ char** official_rules; @@ -778,21 +804,35 @@ attr_index_config( Slapi_PBlock* pb = NULL; int do_continue = 0; /* can we skip the RULE parsing stuff? */ attrValue = slapi_value_get_berval(sval); - - if (strstr(attrValue->bv_val, INDEX_ATTR_SUBSTRBEGIN)) { - _set_attr_substrlen(INDEX_SUBSTRBEGIN, attrValue->bv_val, &substrlens); - do_continue = 1; /* done with j - next j */ - } else if (strstr(attrValue->bv_val, INDEX_ATTR_SUBSTRMIDDLE)) { - _set_attr_substrlen(INDEX_SUBSTRMIDDLE, attrValue->bv_val, &substrlens); - do_continue = 1; /* done with j - next j */ - } else if (strstr(attrValue->bv_val, INDEX_ATTR_SUBSTREND)) { - _set_attr_substrlen(INDEX_SUBSTREND, attrValue->bv_val, &substrlens); - do_continue = 1; /* done with j - next j */ + /* + * In case nsSubstr{Begin,Middle,End}: num is not set, but set by this format: + * nsMatchingRule: nsSubstrBegin=2 + * nsMatchingRule: nsSubstrMiddle=2 + * nsMatchingRule: nsSubstrEnd=2 + */ + if (!a->ai_substr_lens || !a->ai_substr_lens[INDEX_SUBSTRBEGIN]) { + if (PL_strcasestr(attrValue->bv_val, INDEX_ATTR_SUBSTRBEGIN)) { + _set_attr_substrlen(INDEX_SUBSTRBEGIN, attrValue->bv_val, &substrlens); + do_continue = 1; /* done with j - next j */ + } + } + if (!a->ai_substr_lens || !a->ai_substr_lens[INDEX_SUBSTRMIDDLE]) { + if (PL_strcasestr(attrValue->bv_val, INDEX_ATTR_SUBSTRMIDDLE)) { + _set_attr_substrlen(INDEX_SUBSTRMIDDLE, attrValue->bv_val, &substrlens); + do_continue = 1; /* done with j - next j */ + } + } + if (!a->ai_substr_lens || !a->ai_substr_lens[INDEX_SUBSTREND]) { + if (PL_strcasestr(attrValue->bv_val, INDEX_ATTR_SUBSTREND)) { + _set_attr_substrlen(INDEX_SUBSTREND, attrValue->bv_val, &substrlens); + do_continue = 1; /* done with j - next j */ + } + } /* check if this is a simple ordering specification for an attribute that has no ordering matching rule */ - } else if (slapi_matchingrule_is_ordering(attrValue->bv_val, attrsyntax_oid) && - slapi_matchingrule_can_use_compare_fn(attrValue->bv_val) && - !a->ai_sattr.a_mr_ord_plugin) { /* no ordering for this attribute */ + if (slapi_matchingrule_is_ordering(attrValue->bv_val, attrsyntax_oid) && + slapi_matchingrule_can_use_compare_fn(attrValue->bv_val) && + !a->ai_sattr.a_mr_ord_plugin) { /* no ordering for this attribute */ need_compare_fn = 1; /* get compare func for this attr */ do_continue = 1; /* done with j - next j */ } @@ -844,7 +884,9 @@ attr_index_config( slapi_pblock_destroy (pb); } official_rules[k] = NULL; - a->ai_substr_lens = substrlens; + if (substrlens) { + a->ai_substr_lens = substrlens; + } if (k > 0) { a->ai_index_rules = official_rules; a->ai_indexmask |= INDEX_RULES; diff --git a/ldap/servers/slapd/plugin_syntax.c b/ldap/servers/slapd/plugin_syntax.c index 878e107..fa05b0b 100644 --- a/ldap/servers/slapd/plugin_syntax.c +++ b/ldap/servers/slapd/plugin_syntax.c @@ -908,6 +908,19 @@ slapi_attr_assertion2keys_sub_sv( Slapi_Value ***ivals ) { + return slapi_attr_assertion2keys_sub_sv_pb(NULL, sattr, initial, any, final, ivals); +} + +int +slapi_attr_assertion2keys_sub_sv_pb( + Slapi_PBlock *pb, + const Slapi_Attr *sattr, + char *initial, + char **any, + char *final, + Slapi_Value ***ivals +) +{ int rc; Slapi_PBlock pipb; struct slapdplugin *pi = NULL; @@ -927,13 +940,16 @@ slapi_attr_assertion2keys_sub_sv( pi = sattr->a_plugin; a2k_fn = sattr->a_plugin->plg_syntax_assertion2keys_sub; } - pblock_init( &pipb ); - slapi_pblock_set( &pipb, SLAPI_PLUGIN, pi ); + if (NULL == pb) { + pblock_init( &pipb ); + pb = &pipb; + } + slapi_pblock_set( pb, SLAPI_PLUGIN, pi ); rc = -1; /* means no assertion2keys function */ *ivals = NULL; if ( a2k_fn != NULL ) { - rc = (*a2k_fn)( &pipb, initial, any, final, ivals ); + rc = (*a2k_fn)( pb, initial, any, final, ivals ); } LDAPDebug( LDAP_DEBUG_FILTER, diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h index bc68157..fe4f7aa 100644 --- a/ldap/servers/slapd/slapi-plugin.h +++ b/ldap/servers/slapd/slapi-plugin.h @@ -5844,6 +5844,8 @@ int slapi_call_syntax_assertion2keys_ava_sv( void *vpi, Slapi_Value *val, Slapi_Value ***ivals, int ftype ); int slapi_call_syntax_assertion2keys_sub_sv( void *vpi, char *initial, char **any, char *final, Slapi_Value ***ivals ); +int slapi_call_syntax_assertion2keys_sub_sv_pb( Slapi_PBlock *pb, void *vpi, + char *initial, char **any, char *final, Slapi_Value ***ivals ); int slapi_attr_values2keys_sv( const Slapi_Attr *sattr, Slapi_Value **vals, Slapi_Value ***ivals, int ftype ); -- 1.9.3